【问题标题】:Confusion in working of Decimal and Round functionDecimal 和 Round 函数的工作混乱
【发布时间】:2016-09-15 15:07:08
【问题描述】:

我试图了解 Python 的舍入和小数函数实际上是如何工作的。为此,我尝试运行此代码:

from decimal import Decimal print("An integer %i and a float %.1f" %(23, 6.549)) print Decimal(6.549) print Decimal(45.0)/Decimal(7) print Decimal(45.0/7)

我得到了输出:

An integer 23 and a float 6.5
6.54900000000000037658764995285309851169586181640625
6.428571428571428571428571429
6.4285714285714288251938342000357806682586669921875
  1. 我试图从文档here 中了解轮函数的工作原理,它描述了 6.549 被转换为二进制浮点数并被二进制近似值替换。我对 Decimal(6.549) 的扩展值的近似值从何而来感到困惑。另外,我可以假设每个十进制值的四舍五入将以相同的方式工作还是取决于单个二进制近似值?

  2. 当我以两种不同的方式使用 Decimal 函数时,它给出的值略有不同。此外,一个值比另一个值具有更高的精度。有人可以说明原因吗?

提前致谢。

【问题讨论】:

  • Decimal 无法修复已损坏的内容。
  • 您是故意将浮点值传递给 Decimal()(因为您想看看它们的样子)还是想要真正的十进制值? (如果是后者,请在输入周围使用单引号。)
  • 我故意使用浮点值,因为我想看看它们被四舍五入到哪个值。

标签: python-2.7 floating-point decimal rounding decimal-point


【解决方案1】:

我对 Decimal(6.549) 的扩展值的近似值从何而来感到困惑。

文字6.549首先被转换为浮点数,以二进制形式存储:由于6.549不能完全以这种格式存储,所以它被四舍五入到最接近的值,实际上是

6.54900000000000037658764995285309851169586181640625

(详情请参阅Rick Regan's floating point converter)。

要避免这种中间舍入,请改为传递一个字符串:

>>> Decimal("6.549")
Decimal('6.549')

另外,我可以假设每个十进制值的四舍五入将以相同的方式工作还是取决于单个二进制近似值?

是的,所有数字文字都会有这个问题(除非它们可以精确地用二进制表示,例如45.07)。

当我以两种不同的方式使用 Decimal 函数时,它给出的值略有不同。此外,一个值比另一个值具有更高的精度。有人可以说明原因吗?

由于上述相同的问题:Decimal(45.0)/Decimal(7) 将首先将文字 45.07 转换为小数(可以精确地完成),然后使用扩展精度十进制库执行除法。

另一方面,Decimal(45.0/7)45.07 都转换为浮点数(这是精确的),但随后以浮点精度执行除法(仅精确到大约 16 位有效数字)。然后将此结果转换为十进制(包括错误的额外数字)。

【讨论】:

  • 那么,Decimal(45.0/7) 的结果与 Decimal(45.0)/Decimal(7) 的结果相比是不正确的,对吧?
  • 后者更准确,是的:真正的答案是循环小数,因此不能用有限长度的十进制(或二进制)近似值精确表示。
猜你喜欢
  • 2017-03-21
  • 2017-02-15
  • 2018-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
相关资源
最近更新 更多