首页 > 解决方案 > 为什么小数不能与浮点数互操作

问题描述

十进制注释说:

## Decimal has all of the methods specified by the Real abc, but it should
## not be registered as a Real because decimals do not interoperate with
## binary floats (i.e.  Decimal('3.14') + 2.71828 is undefined).  But,
## abstract reals are expected to interoperate (i.e. R1 + R2 should be
## expected to work if R1 and R2 are both Reals).

我不明白为什么Decimal('3.14') + 2.71828 is undefined。十进制可以从浮点数构造,所以我认为__add__可以按如下方式实现:

def __add__(self, other):
    if isinstance(other, float):
        return self + Decimal(other)
    ...

有了它,我们就能得到Decimal('3.14') + 2.71828 = Decimal('3.14') + Decimal(2.71828) = 5.858280000000000153903556566

你能解释一下为什么它们在当前的实现中不能互操作吗?

编辑:在将浮点数转换为十进制时,可以先将其转换为 str 来保存精度:

def __add__(self, other):
    if isinstance(other, float):
        return self + Decimal(str(other))
    ...

从而Decimal('3.14') + 2.71828 = Decimal('3.14') + Decimal('2.71828') = 5.85828不失精度。

标签: pythondecimal

解决方案


关键在于Decimal初始化的方式。

请注意文档中的所有示例Decimal是如何由string. 它允许我们在存储时传递一个数字而不会丢失精度。

number = Decimal('1.1')
print(number)

上面代码的输出总是Decimal('1.1')

尽管Decimal使用 a进行初始化float是可能的,但我们首先会失去我们想要通过使用来实现的目标Decimal,即精度。考虑以下代码行。

number = Decimal(1.1)

里面的值是number什么?在我的例子中,输出是

Decimal('1.100000000000000088817841970012523233890533447265625')

1.1存储在 a 中float,这意味着它会丢失精度。然后我们用它来初始化一个Decimal. 这就是为什么你应该初始化Decimalsusing string,而不是float,以避免丢失精度,这就是Decimal首先使用 using 的全部意义。


推荐阅读