Python 十进制 - 乘以零

Ton*_*pia 9 python arithmetic-expressions decimal

为什么下面的代码会这样:

from decimal import Decimal
result = Decimal('0') * Decimal('0.8881783462119193534061639577')
print(result)
Run Code Online (Sandbox Code Playgroud)

返回0E-28

我已将其追溯到模块中的以下代码:

if not self or not other:
    ans = _dec_from_triple(resultsign, '0', resultexp)
    # Fixing in case the exponent is out of bounds
    ans = ans._fix(context)
    return ans
Run Code Online (Sandbox Code Playgroud)

该代码似乎遵循十进制算术规范,它没有明确建议当我们乘以零时要做什么,指的是另一个标准中的“特殊数字” ,它也没有指定当我们将整数乘以零时我们要做什么:) 所以十进制库做了明确指定的事情:

  • 在舍入之前,结果的系数是通过将操作数的系数相乘来计算的。
  • 四舍五入之前结果的指数是两个操作数的指数之和。
  • 结果的符号是操作数符号的异或。

问题:如果其中一个操作数为零,需要返回系数和指数(即0E-28)吗?在调用乘法函数时我们已经知道该系数是多少。为什么不直接返回零呢?

Ton*_*pia 3

Raymond Hettinger在cpython github上给出了全面的解释:

\n

算术运算中,算术运算规则部分告诉我们:

\n
\n

操作后尾随零不会被删除。

\n
\n

有一些测试用例涵盖乘以零。以下是 multiply.decTest 中的一些内容:

\n
-- zeros, etc.\nmulx021 multiply  0      0     ->  0\nmulx022 multiply  0     -0     -> -0\nmulx023 multiply -0      0     -> -0\nmulx024 multiply -0     -0     ->  0\nmulx025 multiply -0.0   -0.0   ->  0.00\nmulx026 multiply -0.0   -0.0   ->  0.00\nmulx027 multiply -0.0   -0.0   ->  0.00\nmulx028 multiply -0.0   -0.0   ->  0.00\nmulx030 multiply  5.00   1E-3  ->  0.00500\nmulx031 multiply  00.00  0.000 ->  0.00000\nmulx032 multiply  00.00  0E-3  ->  0.00000     -- rhs is 0\nmulx033 multiply  0E-3   00.00 ->  0.00000     -- lhs is 0\nmulx034 multiply -5.00   1E-3  -> -0.00500\nmulx035 multiply -00.00  0.000 -> -0.00000\nmulx036 multiply -00.00  0E-3  -> -0.00000     -- rhs is 0\nmulx037 multiply -0E-3   00.00 -> -0.00000     -- lhs is 0\nmulx038 multiply  5.00  -1E-3  -> -0.00500\nmulx039 multiply  00.00 -0.000 -> -0.00000\nmulx040 multiply  00.00 -0E-3  -> -0.00000     -- rhs is 0\nmulx041 multiply  0E-3  -00.00 -> -0.00000     -- lhs is 0\nmulx042 multiply -5.00  -1E-3  ->  0.00500\nmulx043 multiply -00.00 -0.000 ->  0.00000\nmulx044 multiply -00.00 -0E-3  ->  0.00000     -- rhs is 0\nmulx045 multiply -0E-3  -00.00 ->  0.00000     -- lhs is 0\n
Run Code Online (Sandbox Code Playgroud)\n

从例子中可以看出:

\n
mulx053 multiply 0.9 -0 -> -0.0\n
Run Code Online (Sandbox Code Playgroud)\n

在算术摘要部分,对动机进行了高层解释:

\n
\n

该算术被设计为十进制扩展浮点算术,直接执行人们在学校教授的规则。在给定的工作精度下,尽可能给出精确的未舍入结果(例如,0.9 \xc3\xb7 10 给出 0.09,而不是\n0.089999996),并且在大多数操作中正确保留尾随零(1.23 + 1.27 给出 2.50) ,而不是 2.5)。如果结果超过工作精度,则应用浮点规则。

\n
\n

常见问题解答部分中给出了更多详细信息为什么尾随小数零很重要?

\n