Python和Haskell有C/C++的浮点不确定性问题吗?

2024-06-01 05:07:37 发布

您现在位置:Python中文网/ 问答频道 /正文

首先,我没有用英语学习数学,所以我在课文中可能会用错词。在

浮点数可以是有限的(42.36)和无限的(42.363636…)

C++ >编号存储在基2 < /强>。我们的大脑在10进制下操作浮点数。在

问题是-

many (a lot, actually) of float numbers with base 10, that are finite, have no exact finite representation in base 2, and vice-versa.

这在大多数情况下并不意味着什么。double的最后一位可能会关闭1位—这不是问题。在

当我们计算两个实际上是整数的浮点时,就会出现一个问题。在C++上{{CD2}}会导致^ {< CD3}},也会导致^ {CD4}}。如果你把它转换成整数,那你就有惊喜了。我总是在C中加一个特殊值(对于给定的类型和体系结构,2*最小值),然后用C取整。我应该用Python还是不使用Python?在

我在Python中运行了一些测试,似乎浮点除法的结果总是如预期的那样。但是一些测试是不够的,因为问题是依赖于体系结构的。有人能确定它是否被处理了,在什么级别上-在浮点类型本身还是仅在取整和缩短函数中?在

另外,如果有人能为我刚刚开始的哈斯凯尔澄清同样的事情,那就太好了。在

更新 人们在一份官方文件中指出,浮点运算的不确定性。剩下的问题是-像math这样的函数是ceil来处理它们还是我自己去做?每次我们谈到这些函数时,都必须向初学者指出这一点,否则他们都会遇到这个问题。在


Tags: 函数类型base体系结构数学整数编号many
3条回答

是的,这是Python中的一个问题。在

https://docs.python.org/2/tutorial/floatingpoint.html

格式C和C++用于表示浮点和double是标准化的(IEEE 754),并且你描述的问题是该表示中固有的。由于Python是用C语言实现的,它的浮点类型容易出现同样的舍入问题。在

Haskell的Float和Double是一个更高层次的抽象,但是由于大多数(全部?)现代CPU使用IEEE754进行浮点计算,很可能也会出现这种舍入错误。在

换言之:只有选择基于底层体系结构的浮点类型的语言/库才能在一定程度上规避IEEE754舍入问题,但由于底层硬件不直接支持其他表示,因此必须降低性能。因此,可能大多数语言都会坚持这个标准,尤其是因为它的局限性是众所周知的。在

实数本身,包括浮点数,在任何数学意义上都不是“无限的”。它们可能有无限的十进制表示,但这只是我们编写(或存储在计算机中)方式的技术问题。实际上,IEEE754也指定了+∞和-∞值,这些值是实际的无穷大。。。但它们不代表实数,在数学上在很多方面都很可怕。在

同时……”如果你把它转换成整数,那么无论如何“你不应该”把浮点数转换成整数,这是不可能的:你只能把浮点数取整成整数。如果你用Haskell的round这样做,确实非常安全

Prelude> round $ 99/3
33

虽然ghci用浮点计算除法。在

唯一总是不安全的事情:

  • 当然,从float到int的隐式转换是完全疯狂的,在C语言中肯定是一个错误。Haskell和Python都是正确的强类型,所以这样的事情不会偶然发生。

  • 通常不应期望浮点值与任何特定值完全相等。不管怎样,这样的期望并不是很有用,因为对于实际的实数,任何一个都是一个null set,这大体上意味着两个实数相等的唯一方法是如果有如此深刻的数学原因的话。但是对于任何一个分布,例如物理过程,相等的概率是零,那么你为什么要检查呢?
    只有<比较的数字OTOH是完全安全的(除非您处理的是巨大数字之间非常小的差异,或者您使用它来通过检查>来“模拟”相等)。

相关问题 更多 >