我遇到了Java模数函数的问题。
由于某种原因,当计算机应该等于23时,计算机的-3 % 26
等于-3,因为26小于-3的最低倍数为-26且-3 - -26
为23。
此外,如果你添加26到-3,这实际上是添加模数0,那么结果不应该改变,结果应该变为23.任何人都可以解释为什么Java有-3 % 26 == -3
而不是23以及如何解决这个问题?
答案 0 :(得分:5)
在模数逻辑中,结果值应该是得到0的余数。因此,当你说-3%26时,结果是-3,加上3得到0。
答案 1 :(得分:2)
数学家通常在整数a
被正整数b
除以a - bq
时定义余数,其中商q
是floor(a ÷ b)
。根据此定义,-3
除以26
时的余数为23
,正如您所说。
但是,Java编程语言以不同方式定义了余数。不是使用floor
(即向负无穷大舍入),而是向零舍入。这不会改变正值的答案,但对于负值a
和肯定b
,Java答案比数学家的答案小b
(除非b
完全分开进入a
,在这种情况下,每个人都同意答案是0
)。因此-3 % 26 == 23 - 26 == -3
。
Java程序员通常会调用%
余数运算符,但你是正确的,通常也称为模运算符。在Visual Basic中,它甚至写成Mod
,但它与C / C#/ Java等中的%
一样。
在我看来,向零而不是负无穷的四舍五入是一个错误,它只会让生活更艰难。例如,要测试整数n
是否奇怪,您应该能够if (n % 2 == 1)
,但这不起作用,因为如果n
为负且奇数,答案为{{ 1}}。我不知道它首先使用了哪种语言,但是C,C ++,C#和Java重复了同样的错误。正确进行整数除法的语言(在我看来)包括Python,Ruby和Haskell。
在Java 8中,已经为-1
类添加了方法,用于舍入为负无穷大而不是零的舍入。方法是。
Math
Math.floorDiv(int, int)
Math.floorMod(int, int)
Math.floorDiv(long, long)
Math.floorMod(long, long)
可以根据需要返回Math.floorMod(-3, 26)
。