浮点是如何存储的?什么时候重要?

How is floating point stored? When does it matter?

提问人:Adam Davis 提问时间:9/11/2008 最后编辑:RBTAdam Davis 更新时间:7/17/2019 访问量:23763

问:

这个问题的后续中,似乎有些数字根本不能用浮点数表示,而是近似值。

浮点数是如何存储的?

不同尺寸是否有共同的标准?

如果我使用浮点,我需要注意什么样的陷阱?

它们是否跨语言兼容(即,我需要处理哪些转换才能通过 TCP/IP 将浮点数从 python 程序发送到 C 程序)?

浮点 舍入误差

评论

0赞 RBT 7/17/2019
相关文章 - 浮点数学坏了吗? & 关于计算机中浮点数表示的非常著名的白皮书 - 每个计算机科学家都应该知道的浮点运算
0赞 ChrisN 9/12/2008
文章中对浮点数的问题进行了详尽的解释 每个计算机科学家都应该知道的关于浮点运算的知识。

答:

0赞 Rik 9/11/2008 #1

我记得一个 32 位浮点数是使用 24 位作为实际数字存储的,剩下的 8 位用作 10 的幂,确定小数点的位置。

我对这个话题有点生疏......

5赞 erickson 9/11/2008 #2

该标准是IEEE 754

当然,当 IEE754 不够好时,还有其他方法可以存储数字。像 Java 这样的库可用于大多数平台,并且可以很好地映射到 SQL 的数字类型。符号可用于无理数,无法用二进制或十进制浮点数准确表示的比率可以存储为比率。BigDecimal

2赞 Onorio Catenacci 9/11/2008 #3

这篇题为“IEEE 标准 754 浮点数”的文章可能会有所帮助。老实说,我不完全确定我是否理解你的问题,所以我不确定这是否会有所帮助,但我希望会有所帮助。

2赞 stukelly 9/11/2008 #4

是的,有IEEE二进制浮点运算标准(IEEE 754)

当以二进制形式存储时,该数字分为三部分,符号、指数和分数。

4赞 Craig H 9/12/2008 #5

基本上,在浮点数中,您需要担心的是精度位数有限。在测试相等性时,或者程序实际上需要的精度位数多于该数据类型提供的精度时,这可能会导致问题。

在 C++ 中,一个好的经验法则是认为浮点数为您提供 7 位精度,而双精度为您提供 15 位。此外,如果您有兴趣了解如何测试相等性,可以查看此问题线程。

6赞 Knox 9/12/2008 #6

至于问题的第二部分,除非性能和效率对你的项目很重要,否则我建议你通过 TCP/IP 将浮点数据作为字符串传输。这样可以避免字节对齐等问题,并简化调试。

2赞 Kibbee 9/12/2008 #7

如果您真的担心浮点舍入错误,大多数语言都提供没有浮点错误的数据类型。SQL Server 具有 Decimal 和 Money 数据类型。.Net 具有 Decimal 数据类型。它们不像 Java 中的 BigDecimal 那样具有无限精度,但它们精确到定义的小数点数。因此,您不必担心您输入的 4.58 美元的美元价值会保存为 4.5799999999999997 的浮点值

28赞 Rob Pilkington 9/12/2008 #8

如前所述,维基百科上关于IEEE 754的文章很好地展示了浮点数在大多数系统上的存储方式。

现在,这里有一些常见的问题:

  • 最大的问题是,你几乎从来不想比较两个浮点数的相等性(或不等式)。您需要改用大于/小于比较。
  • 对浮点数执行的运算越多,舍入误差就越大。
  • 精度受分数大小的限制,因此您可能无法正确添加相隔几个数量级的数字。(例如,您将无法将 1E-30 添加到 1E30。
3赞 Thorsten S. 12/8/2009 #9

在跟进这个问题时,它 似乎有些数字不能 完全用浮点表示, 而是近似值。

正确。

浮点数是如何存储的? 不同尺寸是否有共同的标准?

正如其他海报已经提到的,几乎完全是IEEE754及其继任者 IEEE754R。谷歌搜索它为您提供了一千种解释以及位模式及其解释。 如果您仍然无法获取它,还有两种常见的 FP 格式:IBM 和 DEC-VAX。对于一些深奥的机器和编译器(BlitzBasic、TurboPascal),有一些 奇怪的格式。

如果我使用浮点,我需要注意什么样的陷阱? 它们是否跨语言兼容(即,我需要处理哪些转换 通过 TCP/IP 将浮点数从 python 程序发送到 C 程序)?

几乎没有,它们是跨语言兼容的。

非常罕见的怪癖:

  • IEEE754定义了 sNaN(信号 NaN)和 qNaNs(安静 NaN)。前者会导致陷阱,该陷阱会强制处理器在加载时调用处理程序例程。后者不这样做。由于语言设计者讨厌 sNaN 中断其工作流并支持它们强制支持处理程序例程的可能性,因此 sNaN 几乎总是以静默方式转换为 qNaN。 因此,不要依赖 1:1 的原始转换。但同样:这是非常罕见的,只有在 NaN 都存在。

  • 如果在不同计算机之间共享文件,则可能会遇到字节序问题(字节顺序错误)。它很容易被检测到,因为你得到的是数字的 NaN。