直接分配浮点文字float x = 3.2f;
和隐式转换为浮点double
的{{1}}的位表示形式上是否有区别?
即是
float x2 = 3.2;
#define EQUAL(FLOAT_LITERAL)\
FLOAT_LITERAL##f == static_cast<float>(FLOAT_LITERAL)
EQUAL(3.2) && EQUAL(55.6200093490) // etc ...
是否包含所有浮点文字?
我问这个问题,因为如果数字在float的值范围内,那么clang或gcc不会抱怨缩小转换范围:
通过true
启用了警告:
-Wnarrowing
编译器进行实际范围检查很好,但这足够了吗?
答案 0 :(得分:4)
假设采用IEEE 754,浮点数为32位二进制,两倍为64位二进制。
根据IEEE 754舍入至最接近规则,如果将十进制分数直接从十进制转换为浮点数,则首先将其从十进制转换为双精度,然后再转换为浮点数。
例如,考虑1.0000000596046447753906250000000000000000000000000001
1.000000059604644775390625可以精确地表示为双精度值,并且恰好位于1.0和1.00000011920928955078125之间的一半,最小浮点的值大于1.0。如果直接转换,则1.0000000596046447753906250000000000000000000000000001舍入为1.00000011920928955078125,因为它大于中点。如果先将其转换为64位,则四舍五入到最接近值会将其取到中点1.000000059604644775375390625,然后将一半舍入为偶数取整为1.0。
答案 1 :(得分:3)
帕特里夏给出的答案是正确的。但是我们通常不键入这样的数字,所以也许这不是问题……除非它与一些较短的十进制文字一起发生?
我已经在回答Count number of digits after `.` in floating point numbers?之后的评论中举例说明了
十进制值7.038531e-26大约为0x1.5C87FAFFFFFFFCE4F6700 ... p-21,最接近的双精度数为0x1.5C87FB0000000p-21,最接近的浮点数为0x1.5C87FAp-21。
请注意,0x1.5C87FA0000000p-21是最接近7.038530691851209e-26的双精度值
所以是的,可能会有一个双舍入问题(在同一方向上两次舍入误差),字面量相对较短...
如果编译器正确舍入文字, float x = 7.038531e-26f;
和float y = 7.038531e-26;
应该是两个不同的数字。
答案 2 :(得分:1)
文字双浮点转换是否等于浮点文字?
通常是,但not always equal。
编码到 double
然后到 float
(相对于编码到 float
)可能会导致 double rounding 麻烦。
在接近两个相邻 float
值的中途情况的任何代码值(甚至可能没有小数)时看到的问题。
出现次数:随机常数和典型的float/double
:大约 2 分之 130。