python - 为什么小数不能与浮点数互操作
问题描述
十进制注释说:
## 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
不失精度。
解决方案
关键在于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
. 这就是为什么你应该初始化Decimals
using string
,而不是float
,以避免丢失精度,这就是Decimal
首先使用 using 的全部意义。
推荐阅读
- uml - 如何表达树结构约束
- java - 根据计算值对使用 spring JPA 分页的 DB 中的行进行排序
- javascript - .map 从 this.state 做出反应
- python - 不断更新 Tkinter 中的标签
- javascript - Vue Array prop 默认值不起作用
- amazon-web-services - toomanyrequests:您已达到拉取率限制。您可以通过身份验证和升级来增加限制
- c++ - PortAudio 中的输出
- python - 如何创建具有 2 列唯一且自动递增的模型?
- c# - DLL 中的 Microsoft.Graph 集合反序列化
- c++ - Clion:进程以退出代码 139 结束