Bootstrap

整除运算的不同定义,取余运算与取模运算的区别与联系

数学中整除及余数的定义
设a,b是两个整数,且b≠0,则存在唯一的整数q和r使得: a = q × b + r ( 0 ≤ r < ∣ b ∣ ) a=q×b+r(0≤r<|b|) a=q×b+r0r<b)
该式叫做带余除法,记余数 r = a   m o d   b r = a\ mod\ b r=a mod b
数学中的余数一定是非负整数。

数学中(以及python中),整除商为实数商向下取整。
q = ⌊ a b ⌋ q = \lfloor \frac{a}{b} \rfloor q=ba
C++/Java/C#/JavaScript中,整除商为实数商向0取整。
q = ⌊ a b ⌋ ( a b ≥ 0 ) , q = ⌈ a b ⌉ ( a b < 0 ) q=\lfloor \frac{a}{b} \rfloor(\frac{a}{b}\ge0),q=\lceil \frac{a}{b} \rceil(\frac{a}{b}<0) q=baba0)q=baba<0)
余数都为 r = b ∗ q − a r = b*q-a r=bqa
因此两种整除定义下的余数不同。
例:

− 7 ÷ 2 = − 3.5 -7÷2 = -3.5 7÷2=3.5
商向0取整: − 7 = − 3 ∗ 2 − 1 -7 = -3*2-1 7=321,即 − 7 ÷ 2 = − 3...... − 1 -7÷2 = -3......-1 7÷2=3......1(C++取模)
商向下取整: − 7 = − 4 ∗ 2 + 1 -7 = -4*2+1 7=42+1,即 − 7 ÷ 2 = − 4 … … 1 -7÷2 = -4……1 7÷2=4……1(数学取余)

使用C++代码完成数学取余,求a mod b:
商向0取整,则除法等式为 a ÷ b = c . . . . . . d a÷b=c......d a÷b=c......d,其中 d = a % b d=a\%b d=a%b,%为C++取模运算。
满足 a = c ∗ b + d a = c*b+d a=cb+d
商向下取整,除法等式为 a ÷ b = e . . . . . . f a÷b=e......f a÷b=e......f,其中 f = a   m o d   b f = a\ mod\ b f=a mod b,mod为数学取余运算。
满足 a = e ∗ b + f a = e*b+f a=eb+f
因此有: c ∗ b + d = e ∗ b + f c*b+d = e*b+f cb+d=eb+f
如果 d > 0 d>0 d>0,那么 f = d f=d f=d,此时 a   m o d   b = a % b a\ mod\ b=a\%b a mod b=a%b
如果 d = 0 d=0 d=0,那么 f = 0 f=0 f=0,此时 a   m o d   b = a % b a\ mod\ b=a\%b a mod b=a%b
如果 d < 0 d<0 d<0,由于数学中余数不能为负,所以将等式调整为余数大于等于0。

  • 如果除数 b > 0 b>0 b>0,则调整为 c ∗ b + d = ( c − 1 ) ∗ b + ( d + b ) c*b+d = (c-1)*b+(d+b) cb+d=(c1)b+(d+b),因此 f = d + b f=d+b f=d+b,此时 a   m o d   b = a % b + b a\ mod\ b=a\%b+b a mod b=a%b+b
  • 如果除数 b < 0 b<0 b<0,则调整为 c ∗ b + d = ( c + 1 ) ∗ b + ( d − b ) c*b+d=(c+1)*b+(d-b) cb+d=(c+1)b+(db),因此 f = d − b f=d-b f=db,此时 a   m o d   b = a % b − b a\ mod\ b = a\%b-b a mod b=a%bb
  • 综合以上两种情况, a   m o d   b = a % b + ∣ b ∣ a\ mod\ b = a\%b+|b| a mod b=a%b+b

综合以上所有情况,在各种情况下都满足 a   m o d   b = ( a % b + ∣ b ∣ ) % b a\ mod\ b=(a\%b+|b|)\%b a mod b=(a%b+b)%b
即C++中求a mod b的写法为:(a%b+abs(b))%b
(当b为long long类型时,需要自己写求long long类型绝对值的函数)。

;