从双重铸造到浮动

时间:2014-09-14 09:26:04

标签: c casting floating-point double bit-manipulation

我正在读d == (double)(float)d,其中d是double,不会评估为真 这是有道理的,因为我们正在铸造一种较低精度但*我无法理解作为例子给出的数字 如果d为1e40,则表达式将评估为+无穷大 但1e40的位模式是:

1110101100011001010011111000111000011010111001010010010111111101010111011100111110101011000010000000000000000000000000000000000000000

无穷大由指数全1和分数全0表示 那么如何将这个特定的例子减少到无穷大?

3 个答案:

答案 0 :(得分:3)

最大float(IEEE-754 binary32)值约为3.4028234 × 1e38。因此,当double1e40转换为float时,它会产生正无穷大。

答案 1 :(得分:2)

值得注意的是,这可能是未定义的行为,具体取决于float是否支持正无穷大。 N1570§6.3.1.5:

  

当实际浮动类型的值转换为实际浮动时   type,如果要转换的值可以完全表示在   新型,它没有变化。如果转换的值在   可以表示但无法表示的值范围   确切地说,结果是最接近的更高或更接近的更低   可表示的值,以实现定义的方式选择。如果   转换的值超出了可以的值范围   表示,行为未定义。

§5.2.4.2.2/ p5:

  

浮动类型的最小可表示值范围是   在该类型中可表示的最负的有限浮点数   通过可表示的最正的有限浮点数   那种类型。此外,如果负无穷大可以表示为   类型,该类型的范围扩展到所有负实数;   同样,如果正无穷大可以表示类型,范围   这种类型扩展到所有正实数。

如果使用IEEE-754浮点,则1e40超出binary32的可表示有限数范围,并且转换在默认舍入模式下产生正无穷大。

答案 2 :(得分:2)

如果您尝试将问题中的二进制序列转换为float,则在以二进制形式编写之后的下一步将是“规范化”它:

1.11010110001100101001111100011100001101011100101001001011111110… * 2128

在四舍五入到24位有效数字之后:

1.11010110001100101010000 * 2128

对于单精度IEEE 754二进制表示的指数,数字128超出了可接受的范围。标准化数字的指数从-126到+127,有几个例外值用于表示非正规数(包括0),无穷大和NaN。

这就是为什么数字1E38最终表示为float,为+inf,其中一个特殊值是用一个特殊指数编码的,并且没有有效数字1.110101100011 ...你可以期待的。