python负十进制、十进制和正整数的模运算

2024-04-24 04:51:32 发布

您现在位置:Python中文网/ 问答频道 /正文

使用简单的ints:

>>> -45 % 360
315

鉴于,使用decimal.Decimal

>>> from decimal import Decimal
>>> Decimal('-45') % 360
Decimal('-45')

我希望得到Decimal('315')

这有什么原因吗?有没有办法获得一致的行为(无需修补decimal.Decimal)?(我没有改变背景,也找不到如何改变背景来解决这种情况)


Tags: fromimport情况原因decimal背景办法ints
2条回答

经过长时间的搜索(因为搜索“%”、“mod”、“modulo”等会得到上千个结果),我终于意外地发现,this is intended

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:

>>> (-7) % 4
1
>>> Decimal(-7) % Decimal(4)
Decimal('-3')

我不知道这方面的原因,但看起来不可能改变这种行为(不打补丁)

Python的行为符合IBM的General Decimal Arithmetic Specification

{a2}被定义为:

remainder takes two operands; it returns the remainder from integer division. […]

the result is the residue of the dividend after the operation of calculating integer division as described for divide-integer, rounded to precision digits if necessary. The sign of the result, if non-zero, is the same as that of the original dividend.

因此,因为Decimal('-45') // D('360')Decimal('-0'),剩余部分只能是Decimal('-45')

为什么商是0而不是-1?报告说:

divide-integer takes two operands; it divides two numbers and returns the integer part of the result. […]

the result returned is defined to be that which would result from repeatedly subtracting the divisor from the dividend while the dividend is larger than or equal to the divisor. During this subtraction, the absolute values of both the dividend and the divisor are used: the sign of the final result is the same as that which would result if normal division were used. […]

Notes: […]

  1. The divide-integer and remainder operations are defined so that they may be calculated as a by-product of the standard division operation (described above). The division process is ended as soon as the integer result is available; the residue of the dividend is the remainder.

你能从45减去360多少次?0次。是否有整数结果?它是。然后商是0,带负号,因为divide运算表示

The sign of the result is the exclusive or of the signs of the operands.

至于为什么十进制规范采用这种方法,而不是像数学中那样,余数总是正的,我猜测这可能是因为减法算法的简单性。计算商的绝对值不需要检查操作数的符号。无论如何,现代实现可能使用更复杂的算法,但在标准形成、硬件更简单(晶体管更少)的年代,简单性可能是一个重要因素。有趣的事实:英特尔只是在2007年发布了Penryn之后才从基数2整数除法转换为基数16

相关问题 更多 >