【QT】float double的范围与精度及Qt中的qfloat16

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;
#else
typedef 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;
#endif

private:
    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);
### 回答1: 在Qt,将double类型转换为int类型可以使用int()函数。int()函数可以将double类型数据向下取整为int类型数据,例如: double d = 3.14; int i = int(d); // i的值为3 需要注意的是,如果double类型数据是负数时,int()函数会向下取整,即取绝对值并向下取整,然后再给结果加上符号,例如: double d = -3.14; int i = int(d); // i的值为-3 另外,在将double类型数据转换为int类型数据时,也可以使用qRound()函数。qRound()函数可以将double类型数据四舍五入为最接近的整数,然后返回int类型数据,例如: double d = 3.6; int i = qRound(d); // i的值为4 总之,在Qtdouble类型转换为int类型可以使用int()函数或qRound()函数,根据需求选择即可。 ### 回答2: 在Qt编程,将double转换成int是一个非常常见的操作,可以通过几种方法实现。 首先是使用Qt自带的函数来进行转换。Qt提供了两个函数可以将double类型转换成int类型:qRound和qFloor。qRound函数返回最接近参数的整数,其0.5向上舍入。qFloor函数返回不大于参数的最大整数。两个函数都需要添加Qt头文件#include <QtCore>,可以如下编写代码: ```c++ double d = 3.14; int i = qRound(d); // i = 3 int j = qFloor(d); // j = 3 ``` 另外,也可以使用C++标准库的强制类型转换来将double转换成int。通常情况下,可以使用static_cast或者(int)强制转换。如下代码: ```c++ double d = 3.14; int i = static_cast<int>(d); // i = 3 int j = (int)d; // j = 3 ``` 需要注意的是,使用强制类型转换时,如果double超出了int的范围,则会出现不可预料的错误。因此,需要在进行转换之前进行判断,以确保转换安全。 在实际编程,选择哪种转换方式取决于具体的场景和需求。通常情况下,使用Qt提供的函数可以更加方便和可靠。 ### 回答3: 在Qtdouble类型与int类型是不同的数据类型,它们各自有其自己的特点和用途。如果需要将一个double类型的变量或值转换成int类型的变量或值,可以使用Qt提供的一些函数和方法来实现。 其,最常用的是Qt的qRound函数。qRound函数用于将输入的double类型的值四舍五入成最接近的整数,并返回转换后的int类型值。使用此函数的方法如下: ```cpp double num1 = 3.14; int num2 = qRound(num1); // num2的值为3 ``` 除了qRound函数外,还可以使用其他的函数和方法实现double类型与int类型之间的转换。例如,可以使用标准库的强制类型转换来实现: ```cpp double num1 = 3.14; int num2 = static_cast<int>(num1); // num2的值为3 ``` 需要注意的是,double类型的变量或值转换成int类型时会发生精度损失,这可能会引起一些问题。因此,在进行double类型与int类型之间的转换时,需要考虑输入数据的精度精度损失的影响,并做好相应的处理和校验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值