通过应用 (Decimal(), signed numbers ) 在 python 中使用 (%, //) 背后的数学计算?
The math calculations behind using (%, //) in python by applying (Decimal(), signed numbers )?
我试图通过做一些试验来理解使用 / 和 // 和 % 运算符计算背后的数学原理,发现结果仅在使用 Decimal() 时才类似于计算器,但如果没有它,结果有点令人困惑,我试过了在我的代码中添加注释 #No Idea
以标记我不理解的地方,例如:
在这个 % 运算符的试验中,通过应用有符号和无符号数字的结果以及有和没有 Decimal() 的结果是:
>>> 9%5 #This result will be the reminder
4
>>> (-9)%5 #No Idea
1
>>> Decimal(9)% Decimal(5) #This result will be the reminder
Decimal('4')
>>> Decimal(-9)% Decimal(5) #The result will be the signed reminder
Decimal('-4')
在这个针对 // 运算符的试验中,使用带和不带 Decimal() 的有符号和无符号数,结果是:
>>> 9//5 #int result
1
>>> -9//5 #No Idea
-2
>>> Decimal(9)/Decimal(5) #Same result as using calculator
Decimal('1.8')
>>> Decimal(-9)//Decimal(5) #No Idea
Decimal('-1')
请考虑这个问题不是重复的,我已经做了一些研究来得到答案,但我发现一些回答的问题只解释了 // operator using only positive signed numbers and does not include information about negative numbers有符号数或使用 Decimal() 并且没有关于 % 运算符的答案。
所以,如果有人知道为什么结果不同以及它们是如何计算的,那将会很有帮助。
据我了解,OP 询问的是 Python 整数和 Decimal
之间的不同行为。我认为没有任何充分的理由。两种选择都是可能的,但它们的不同会让用户感到有点困惑。
让我们调用分子n
、分母d
并将结果拆分为整数结果i
和余数r
。这意味着
n // d = i
n % d = r
为了使操作有意义,我们需要
i * d + r == n
对于 n = -9
和 d = 5
我们看到 i = -1, r = -4
和 i = -2, r = 1
都支持这一点,正如
所见
(i = -1, r = -4) => -1 * 5 + -4 == -9
(i = -2, r = 1) => -2 * 5 + 1 == -9
现在,在 Python 中,整数除法被定义为始终向负无穷大(向下)截断,并且 Decimal
实现已选择向零舍入。这意味着正值向下 truncated/rounded,而负值向上舍入。
向零四舍五入也是C语言中的选择。但是,我个人认为 Python 选择更加明智,特别是来自硬件背景。鉴于这是在 Python 中做出的选择,我认为 Decimal
选择像在 C 语言中那样做很奇怪(而且很糟糕)。
整数行为的解释
Division of integers yields a float, while floor division of integers
results in an integer; the result is that of mathematical division
with the ‘floor’ function applied to the result.
因此,负负数和正数的整数除法(//
)的工作原理如下:
-9 // 5 == floor(-9 / 5) == floor(-1.8) == -2
模运算符是整数除法的余数,即x % y = x - x // y * y
。在你的例子中:
-9 % 5 == -9 - (-9 // 5 * 5) == (-9) - (-2 * 5) == (-9) - (-10) == 1
文档还说:
The modulo operator always yields a result with the same sign as its
second operand (or zero); the absolute value of the result is strictly
smaller than the absolute value of the second operand.
但这自然来自上面的公式,例如:
9 % -5 == 9 - (9 // (-5) * (-5)) == 9 - (-2 * (-5)) == 9 - 10 == -1
decimal.Decimal
不同
The documentation 很好地解释了差异:
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')
The integer division operator //
behaves analogously, returning the
integer part of the true quotient (truncating towards zero) rather
than its floor, so as to preserve the usual identity x == (x // y) * y
+ x % y
:
>>> -7 // 4
-2
>>> Decimal(-7) // Decimal(4)
Decimal('-1')
我试图通过做一些试验来理解使用 / 和 // 和 % 运算符计算背后的数学原理,发现结果仅在使用 Decimal() 时才类似于计算器,但如果没有它,结果有点令人困惑,我试过了在我的代码中添加注释 #No Idea
以标记我不理解的地方,例如:
在这个 % 运算符的试验中,通过应用有符号和无符号数字的结果以及有和没有 Decimal() 的结果是:
>>> 9%5 #This result will be the reminder 4 >>> (-9)%5 #No Idea 1 >>> Decimal(9)% Decimal(5) #This result will be the reminder Decimal('4') >>> Decimal(-9)% Decimal(5) #The result will be the signed reminder Decimal('-4')
在这个针对 // 运算符的试验中,使用带和不带 Decimal() 的有符号和无符号数,结果是:
>>> 9//5 #int result 1 >>> -9//5 #No Idea -2 >>> Decimal(9)/Decimal(5) #Same result as using calculator Decimal('1.8') >>> Decimal(-9)//Decimal(5) #No Idea Decimal('-1')
请考虑这个问题不是重复的,我已经做了一些研究来得到答案,但我发现一些回答的问题只解释了 // operator using only positive signed numbers and does not include information about negative numbers有符号数或使用 Decimal() 并且没有关于 % 运算符的答案。
所以,如果有人知道为什么结果不同以及它们是如何计算的,那将会很有帮助。
据我了解,OP 询问的是 Python 整数和 Decimal
之间的不同行为。我认为没有任何充分的理由。两种选择都是可能的,但它们的不同会让用户感到有点困惑。
让我们调用分子n
、分母d
并将结果拆分为整数结果i
和余数r
。这意味着
n // d = i
n % d = r
为了使操作有意义,我们需要
i * d + r == n
对于 n = -9
和 d = 5
我们看到 i = -1, r = -4
和 i = -2, r = 1
都支持这一点,正如
(i = -1, r = -4) => -1 * 5 + -4 == -9
(i = -2, r = 1) => -2 * 5 + 1 == -9
现在,在 Python 中,整数除法被定义为始终向负无穷大(向下)截断,并且 Decimal
实现已选择向零舍入。这意味着正值向下 truncated/rounded,而负值向上舍入。
向零四舍五入也是C语言中的选择。但是,我个人认为 Python 选择更加明智,特别是来自硬件背景。鉴于这是在 Python 中做出的选择,我认为 Decimal
选择像在 C 语言中那样做很奇怪(而且很糟糕)。
整数行为的解释
Division of integers yields a float, while floor division of integers results in an integer; the result is that of mathematical division with the ‘floor’ function applied to the result.
因此,负负数和正数的整数除法(//
)的工作原理如下:
-9 // 5 == floor(-9 / 5) == floor(-1.8) == -2
模运算符是整数除法的余数,即x % y = x - x // y * y
。在你的例子中:
-9 % 5 == -9 - (-9 // 5 * 5) == (-9) - (-2 * 5) == (-9) - (-10) == 1
文档还说:
The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand.
但这自然来自上面的公式,例如:
9 % -5 == 9 - (9 // (-5) * (-5)) == 9 - (-2 * (-5)) == 9 - 10 == -1
decimal.Decimal
不同
The documentation 很好地解释了差异:
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')
The integer division operator
//
behaves analogously, returning the integer part of the true quotient (truncating towards zero) rather than its floor, so as to preserve the usual identityx == (x // y) * y + x % y
:>>> -7 // 4 -2 >>> Decimal(-7) // Decimal(4) Decimal('-1')