【QT】float double的范围与精度及Qt中的qfloat16
来源:互联网 发布:老版书旗小说软件 编辑:程序博客网 时间:2024/06/06 12:41
1、格式
float和double都是浮点数据类型,前者为单精度占四个字节,后者为双精度占八个字节。浮点数的存储格式采用IEEE标准,float包括1个符号位、8个指数位和23个尾数位,double包括1个符号位、11个指数位和52个尾数位,其中符号位表示正负,为1时表示负数,为0时表示正数。
2、范围
浮点数的范围由指数决定,以float为例,指数共8个二进制位,以无符号形式存储,指数范围为0~255,但实际的指数值需要减去127,也就是说实际的指数范围为-127~128,其中负指数决定了浮点数绝对值最小的非零值,正指数决定了浮点数绝对值的最大值即取值范围,所以float的范围为-2^128~2^128,换算成十进制科学计数法为-3.40e+38~3.40e+38。同理,double的指数范围为-1023~1024,取值范围为-2^1024~2^1024,即-1.79e+308~1.79e+308。另外,浮点数的最小值可以说是几乎等于0,无限接近于0但不等于0,float和double的最小值理论上是不等的。
3、精度
浮点数的精度由尾数决定,由于是以科学记数法存储的,所以整数部分总是隐含着一个1但对精度没有影响,以float为例,尾数共23个二进制位,2^23=8388608,共7位,所以精度为6~7位有效数字。同理,double的2^52=4503599627370496共16位,所以精度为15~16位有效数字。
4、例子
下面是float的一个例子。
十进制 -5.625 = 十六进制 C0B4 0000转换成二进制为1100 0000 1011 0100 0000 0000 0000 0000按照浮点数格式(1个符号位+8个指数位+23个尾数位)划分为1 1000 0001 01101 000000000000000000其中,符号1表示负数;指数1000 0001即129,减去127为2; 尾数01101 000000000000000000即01101,加上隐含的整数部分为1.101101。所以,最后的结果= -1.01101 × 2^2= -(1*2^0 + 1*2^(-2) + 1*2^(-3) + 1*2^(-5)) * 2^2= -(1+0.25+0.125+0.03125) * 4= -1.40625 * 4= -5.625
5、Qt
在Qt中,除了标准的数据类型包括浮点类型之外,还typedef了一些其它类型,其实就是给标准类型换个好认的名称而已。以qreal为例,在Qt中浮点类型用qreal表示,可能为float或double,如下所示:
#if defined(QT_COORD_TYPE)typedef QT_COORD_TYPE qreal;#elsetypedef double qreal;#endif
Qt还提供了特殊的半精度浮点类型qfloat16,遵循IEEE754标准,1个符号位、5个指数位和10个尾数位,内部用quint16即unsigned short进行存储,如下所示:
class qfloat16{public:#ifndef Q_QDOC Q_DECL_CONSTEXPR inline qfloat16() Q_DECL_NOTHROW : b16(0) { } inline qfloat16(float f) Q_DECL_NOTHROW; inline operator float() const Q_DECL_NOTHROW;#endifprivate: quint16 b16; Q_CORE_EXPORT static const quint32 mantissatable[]; Q_CORE_EXPORT static const quint32 exponenttable[]; Q_CORE_EXPORT static const quint32 offsettable[]; Q_CORE_EXPORT static const quint32 basetable[]; Q_CORE_EXPORT static const quint32 shifttable[]; friend bool qIsNull(qfloat16 f) Q_DECL_NOTHROW; friend qfloat16 operator-(qfloat16 a) Q_DECL_NOTHROW;};
在对qfloat16进行处理时,通过重载的operator float()
及static_cast把qfloat16转换成了float进行处理,根据其存储格式实现了如下几个函数:
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2);bool qIsFinite(qfloat16 f);bool qIsInf(qfloat16 f);bool qIsNaN(qfloat16 f);qint64 qRound64(qfloat16 value);int qRound(qfloat16 value);
- 【QT】float double的范围与精度及Qt中的qfloat16
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- float与double的范围和精度
- spark性能优化之数据倾斜
- java中的各种数据类型在内存中存储的方式
- xgboost安装/git操作
- ZooKeeper系列
- PHP发送短信验证码
- 【QT】float double的范围与精度及Qt中的qfloat16
- redis for mac make安装
- 移动端分辨率与单位转换
- 数学建模(2)——改进的遗传算法(GA)
- Ubuntu下redis安装及其操作
- java enum枚举类型 之 括号赋值
- ubuntu16.04安装Android7
- 定时器&&三次握手&&滑动窗口&&DNS
- 基于HtmlUnit实现简单登录、页面跳转以及获取有用数据部分代码示例(示例网站:大润发)