为什么 Decimal modulo 给出错误的符号?
Why does Decimal modulo give the wrong sign?
花了很长时间来追踪一个错误,这个错误基本上归结为我假设以下两个模都会 return 结果大于 0:
>>> -0.09 % 0.1
0.010000000000000009 # OK
>>> Decimal('-0.09') % Decimal('0.1')
Decimal('-0.09') # Not OK -- I expected a positive value!
这种行为似乎违背了Python docs:
The modulo operator always yields a result with the same sign as its second operand (or zero)
这是一个错误,还是我做错了什么?
您正在查看错误的文档:您链接的段落适用于内置数字类型(尽管这一点并不明显)。对于 decimal
,您需要查看 documentation of decimal
。上面写着:
remainder(x, y)
Returns the remainder from integer division.
The sign of the result, if non-zero, is the same as that of the original dividend.
此外:
The %
and //
operators implement the remainder
and divide-integer
operations (respectively) as described in the specification.
这种行为不一致的事实当然很烦人。
这不是错误。这是 Decimal 在 Python 中的(不幸的)工作方式,它与整数或浮点数不一致:
There are some small differences between arithmetic on Decimal objects and arithmetic on integers and floats. When the remainder operator % is applied to Decimal objects, the sign of the result is the sign of the dividend rather than the sign of the divisor:
花了很长时间来追踪一个错误,这个错误基本上归结为我假设以下两个模都会 return 结果大于 0:
>>> -0.09 % 0.1
0.010000000000000009 # OK
>>> Decimal('-0.09') % Decimal('0.1')
Decimal('-0.09') # Not OK -- I expected a positive value!
这种行为似乎违背了Python docs:
The modulo operator always yields a result with the same sign as its second operand (or zero)
这是一个错误,还是我做错了什么?
您正在查看错误的文档:您链接的段落适用于内置数字类型(尽管这一点并不明显)。对于 decimal
,您需要查看 documentation of decimal
。上面写着:
remainder(x, y)
Returns the remainder from integer division.
The sign of the result, if non-zero, is the same as that of the original dividend.
此外:
The
%
and//
operators implement theremainder
anddivide-integer
operations (respectively) as described in the specification.
这种行为不一致的事实当然很烦人。
这不是错误。这是 Decimal 在 Python 中的(不幸的)工作方式,它与整数或浮点数不一致:
There are some small differences between arithmetic on Decimal objects and arithmetic on integers and floats. When the remainder operator % is applied to Decimal objects, the sign of the result is the sign of the dividend rather than the sign of the divisor: