C 为什么frexp/ldexp有效位的范围在[0.5,1.0]之间?

C 为什么frexp/ldexp有效位的范围在[0.5,1.0]之间?,c,floating-point,ieee-754,c-standard-library,C,Floating Point,Ieee 754,C Standard Library,当IEEE 745浮点值的有效位范围为时,为什么frexp/ldexp函数的有效位范围在[0.5,1.0]之间[1.0,2)?对于任何非0或非规范的有效浮点值,尾数的高位始终为1。IEEE-754利用这一点,不将其编码为二进制值,从而挤出一个额外的精度位。Like double有53位精度,但只编码52位。因此,编码值永远不小于1,range为[1.0..2) 但一旦需要实际值,比如printf()时它或计算需要完成,然后该位需要从编码值还原。通常在处理器的浮点执行单元内部完成。否则,英特尔x8

当IEEE 745浮点值的有效位范围为时,为什么frexp/ldexp函数的有效位范围在[0.5,1.0]之间[1.0,2)?

对于任何非0或非规范的有效浮点值,尾数的高位始终为1。IEEE-754利用这一点,不将其编码为二进制值,从而挤出一个额外的精度位。Like double有53位精度,但只编码52位。因此,编码值永远不小于1,range为[1.0..2)


但一旦需要实际值,比如printf()时它或计算需要完成,然后该位需要从编码值还原。通常在处理器的浮点执行单元内部完成。否则,英特尔x87 FPU设计臭名昭著的80位内部格式背后的灵感。因此,实际范围是[0.5..1).frexp函数与实际值一起工作。

C89和C99标准附带的基本原理文档对此没有说明。合理的猜测是,之所以选择此规范化,是因为创建C的人对它很熟悉,因为DEC体系结构上的浮点格式使用了规范化为的尾数[0.5,1),而不是为后面介绍的IEEE格式选择[1,2]。“那么为什么frexp()将基数放在隐式位的左侧,并返回[0.5,1]中的数字,而不是像[1,2]这样的科学符号?”——“也许frexp返回的格式对于PDP-11的浮点格式是有意义的”我不明白。恢复的是什么?你说的“实际值”是什么意思?嗯,你必须更多地了解浮点值的编码方式来理解它。这不是非常直观。关键是你可以从52个存储位中获得53位精度。维基百科有很多关于它的资料,请查看例如,“双精度”文章。我非常清楚IEEE 745浮点值是如何工作的。我仍然不知道尾数的隐含位与范围[0.5,1.0]有什么关系。这就是你需要解释的。我不得不不同意你的断言,即非编码位以某种方式暗示了[0.5,1.0)。如果浮点数是33位,并且有一个完整的24位尾数,那么它不会改变任何东西。在我看来,这是一个任意的选择,而且逻辑性较差。对于规范化浮点数,尾数的范围是[1.0,2.0],对于非规范化浮点数,尾数的范围是[0.0,1.0],两者都不是[0.5,1.0]。