从字面量到浮点数的转换等于浮点数吗?

时间:2019-03-28 23:08:49

标签: c++ math floating-point

直接分配浮点文字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

编译器进行实际范围检查很好,但这足够了吗?

3 个答案:

答案 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