为什么我在使用 math.fmod 和 mod 运算符时会得到不同的答案? (对于整数)
Why do I get different answers when I use math.fmod and just the mod operator? (for integers)
我写了下面的代码来求最大乘积子数组:
def ans(arr, n):
M = 1000000007
cur_max = cur_min = ans = arr[0] % M
for i in range(1, n):
tmp = cur_max
cur_max = max(arr[i], cur_min * arr[i]% M, cur_max * arr[i] % M)
cur_min = min(arr[i], cur_min * arr[i] % M, tmp * arr[i] % M)
ans = max(ans, cur_max)
return ans % M
当我使用它的时候
array = [6, -3, -10, 0, 2],我得到一个答案:999999989
然而,当我将其更改为
from math import *
def ans(arr, n):
M = 1000000007
cur_max = cur_min = ans = arr[0]
for i in range(1, n):
tmp = cur_max
cur_max = max(arr[i], int(fmod(cur_min * arr[i], M)), int(fmod(cur_max * arr[i], M)))
cur_min = min(arr[i], int(fmod(cur_min * arr[i], M)), int(fmod(tmp * arr[i], M)))
ans = max(ans, cur_max)
return ans
我得到答案:180
我所做的唯一更改是使用 fmod 函数,然后将其转换为整数,而不是使用 mod (%) 运算符。为什么我得到完全不同的答案?
%
运算符和 math.fmod
不执行相同的模运算。具体负数的处理方式不同:
math.fmod(x, y)
[..] The intent of the C standard is that fmod(x, y)
be exactly (mathematically; to infinite precision) equal to x - n*y
for some integer n
such that the result has the same sign as x
and magnitude less than abs(y)
. Python’s x % y
returns a result with the sign of y
instead, and may not be exactly computable for float arguments. [..]
Binary arithmetic operations
[..] The modulo operator always yields a result with the same sign as its second operand (or zero); [..] The function math.fmod()
returns a result whose sign matches the sign of the first argument instead [..]. Which approach is more appropriate depends on the application.
>>> def test_mod(a, b): print('%-op:', a % b, 'fmod:', fmod(a, b))
>>> test_mod(10, 12)
%-op: 10 fmod: 10.0
>>> test_mod(-10, 12)
%-op: 2 fmod: -10.0
>>> test_mod(10, -12)
%-op: -2 fmod: 10.0
两个 ans
变体将为 positive 输入提供相同的结果:
>>> perc_ans([6, 3, 10, 0, 2], 5)
180
>>> math_ans([6, 3, 10, 0, 2], 5)
180
>>> perc_ans([6, -3, -10, 0, 2], 5)
999999989
>>> math_ans([6, -3, -10, 0, 2], 5)
180
我写了下面的代码来求最大乘积子数组:
def ans(arr, n):
M = 1000000007
cur_max = cur_min = ans = arr[0] % M
for i in range(1, n):
tmp = cur_max
cur_max = max(arr[i], cur_min * arr[i]% M, cur_max * arr[i] % M)
cur_min = min(arr[i], cur_min * arr[i] % M, tmp * arr[i] % M)
ans = max(ans, cur_max)
return ans % M
当我使用它的时候
array = [6, -3, -10, 0, 2],我得到一个答案:999999989
然而,当我将其更改为
from math import *
def ans(arr, n):
M = 1000000007
cur_max = cur_min = ans = arr[0]
for i in range(1, n):
tmp = cur_max
cur_max = max(arr[i], int(fmod(cur_min * arr[i], M)), int(fmod(cur_max * arr[i], M)))
cur_min = min(arr[i], int(fmod(cur_min * arr[i], M)), int(fmod(tmp * arr[i], M)))
ans = max(ans, cur_max)
return ans
我得到答案:180
我所做的唯一更改是使用 fmod 函数,然后将其转换为整数,而不是使用 mod (%) 运算符。为什么我得到完全不同的答案?
%
运算符和 math.fmod
不执行相同的模运算。具体负数的处理方式不同:
math.fmod(x, y)
[..] The intent of the C standard is that
fmod(x, y)
be exactly (mathematically; to infinite precision) equal tox - n*y
for some integern
such that the result has the same sign asx
and magnitude less thanabs(y)
. Python’sx % y
returns a result with the sign ofy
instead, and may not be exactly computable for float arguments. [..]
Binary arithmetic operations
[..] The modulo operator always yields a result with the same sign as its second operand (or zero); [..] The function
math.fmod()
returns a result whose sign matches the sign of the first argument instead [..]. Which approach is more appropriate depends on the application.
>>> def test_mod(a, b): print('%-op:', a % b, 'fmod:', fmod(a, b))
>>> test_mod(10, 12)
%-op: 10 fmod: 10.0
>>> test_mod(-10, 12)
%-op: 2 fmod: -10.0
>>> test_mod(10, -12)
%-op: -2 fmod: 10.0
两个 ans
变体将为 positive 输入提供相同的结果:
>>> perc_ans([6, 3, 10, 0, 2], 5)
180
>>> math_ans([6, 3, 10, 0, 2], 5)
180
>>> perc_ans([6, -3, -10, 0, 2], 5)
999999989
>>> math_ans([6, -3, -10, 0, 2], 5)
180