Python: 为什么小数是近似的?

Python: Why are decimals approximated?

我正在试验 IDLE Python 3.4.0 shell,并执行了以下代码。

>>> from decimal import *
>>> getcontext().prec = 500
>>> e = Decimal(2.4)
>>> print(e)
2.399999999999999911182158029987476766109466552734375

如您所见,我将变量 e 设置为恰好等于 2.4,仅此而已。但是,当我打印 e,而不是打印 2.42.400000... 时,它打印了您在上面看到的内容。然后我尝试将 getcontext().prec 更改为 5,它仍然打印出完全相同的结果。现在,为了重复我的实验,我测试了一个整数,然后是另一个小数。

>>> f = Decimal(10)
>>> print(f)
10
>>> g = Decimal(10.1)
>>> print(g)
10.0999999999999996447286321199499070644378662109375

只有当我用小数 class 分配一个非整数时,才会打印出奇怪的十进制数字串。 最后,我用浮点数测试了这个。

>>> h = float(2.4)
>>> print(h)
2.4
>>> i = float(10.1)
>>> print(i)
10.1

为什么小数 class 会产生这些奇怪的小数串而不是确切的数字?

这与 Python 无关,这只是计算机处理浮点运算的方式。

假设您正在尝试以 10 为基数准确地写下小数的 1/3 - 您做不到,因为您没有无限的时间或纸张。 (0.333333...) 3有无限多个,所以任何十进制表示都只能是一个近似值。

同样,计算机无法以完美的精度表示某些分数。 (因为它们没有无限内存)所以在这种情况下,计算机最接近 10.1 的是 10.0999999999999996447286321199499070644378662109375。这与 getcontext() 或任何其他无关,因为计算机无法完全准确地存储 10.1 或 2.4。

当您将文字 2.4 传递给 Decimal 时,您正在从浮点数 2.4 创建一个 Decimal。浮点数的值已经近似,Decimal 无法取回 "exactness"。

要准确创建 Decimal(2.4),您可以传递一个字符串

>>> from decimal import *
>>> getcontext().prec = 500
>>> e = Decimal('2.4')
>>> e
Decimal('2.4')

或对从整数派生的小数使用除法

>>> Decimal(24)/10
Decimal('2.4')