控制台上的Python Decimal精度-很奇怪



在3中导入了数学和小数。我对第一个输出没问题

In[39]:  Decimal(sqrt(2))
Out[39]: Decimal('1.4142135623730951454746218587388284504413604736328125')

但随后受到的轻微干扰

In[40]:  Decimal(str(sqrt(2)))
Out[40]: Decimal('1.4142135623730951')

被弄糊涂了

In[41}:  getcontext().prec=2
In[42]:  Decimal(str(sqrt(2)))
Out[42]: Decimal('1.4142135623730951')

为什么prec=2之后的未来Decimal Out[]行的输出精度没有设置为2?我认为Decimal()将输入(无论是float字符串还是int)强制转换为精度设置为十进制?

正如文档所说的Decimal()构造函数:

上下文精度不影响存储的位数。这完全由值中的位数决定。例如,Decimal('3.000000')记录所有五个零,即使上下文精度只有三。

去除多余精度的一种方法是将一元+运算符应用于结果:

>>> decimal.Decimal(str(math.sqrt(2)))
Decimal('1.4142135623730951')
>>> + decimal.Decimal(str(math.sqrt(2))) # note the leading "+"
Decimal('1.4')

另一种是使用上下文对象的.create_decimal()方法:

>>> decimal.getcontext().create_decimal(str(math.sqrt(2)))
Decimal('1.4')

正如create_decimal的文档所说:

与Decimal构造函数不同,上下文精度、舍入方法、标志和陷阱都应用于转换。

来自文档:

Decimal的重要性仅由输入的位数决定。上下文精度和舍入只在算术运算过程中发挥作用。

由于您没有在Decimal(str(sqrt(2)))上进行任何运算,因此它没有使用您设置的精度。您可以通过添加一个琐碎的算术运算来解决此问题。

In: Decimal(str(sqrt))) + 0
Out: Decimal('1.4')

关于第2部分浮点str(v)的输出v显示了v == float(str(v))为真的最短表示。

Python文档说:

由于值的显示方式,许多用户不知道近似值。Python只打印机器存储的二进制近似值的真正十进制值的十进制近似值。在大多数机器上,如果Python要打印为0.1存储的二进制近似值的真正十进制值,它必须显示

>>> 0.1
0.1000000000000000055511151231257827021181583404541015625

这比大多数人认为有用的数字要多,所以Python通过显示四舍五入值而不是来保持数字数量的可管理性

>>> 1 / 10
0.1

请记住,即使打印的结果看起来像1/10的精确值,但实际存储的值是最接近的可表示二进制分数。

关于第3部分,Python文档说:

上下文精度不会影响存储的位数。这完全由值中的位数决定。例如,Decimal('300000')记录所有五个零,即使上下文精度只有三个

最新更新