我正在试验负基数系统,我用Excel来玩并检查我的计算.
我注意到C#与Excel存在差异.为什么C#返回的结果与Excel不同?
例如:
C#:146%-3 = 2
Excel:mod(146,-3)= -1
Eri*_*ert 11
假设我们有四个整数:x,y,q和r这样
q = x / y
r = x - q * y
Run Code Online (Sandbox Code Playgroud)
我希望商和其余部分必须有这种关系才有意义.
现在我们来看看C#和Excel之间的区别.差异实际上是分裂,而不是剩余部分.计算两个整数的商时,C#向零舍入,Excel向下舍入.也就是说,在C#8/-3中是-2,在excel中,INT(8/-3)是-3.
从这个事实,你可以推断为什么剩余的不同.
正如维基百科的文章所说,模运算是除数%divisor == remainder.当任一操作数为负值时,问题就出现了.在那时,天真的数学定义崩溃了,结果变得依赖于实现.
在Excel中,mod运算符始终返回与除数符号相同的结果.在数学上,模运算中使用的商是向下舍入的(朝向-∞).在伪代码中:
quotient = floor(dividend / divisor)
mod = dividend - (divisor * quotient)
Run Code Online (Sandbox Code Playgroud)
因此,对于146和-3:
quotient = -49 // floor(146 / -3)
mod = -1 // 146 - (-3 * -49) == 146 - 147
Run Code Online (Sandbox Code Playgroud)
在C#中,它是相反的:结果始终与被除数具有相同的符号.这是因为商被截断为0.在伪代码中:
quotient = truncate(dividend / divisor)
mod = dividend - (divisor * quotient)
Run Code Online (Sandbox Code Playgroud)
因此:
quotient = -48 // truncate(146 / -3)
mod = 2 // 146 - (-3 * -48) == 146 - 144
Run Code Online (Sandbox Code Playgroud)