模数运算符对负数不正确

时间:2015-03-23 01:48:41

标签: java

我遇到了Java模数函数的问题。

由于某种原因,当计算机应该等于23时,计算机的-3 % 26等于-3,因为26小于-3的最低倍数为-26且-3 - -26为23。

此外,如果你添加26到-3,这实际上是添加模数0,那么结果不应该改变,结果应该变为23.任何人都可以解释为什么Java有-3 % 26 == -3而不是23以及如何解决这个问题?

2 个答案:

答案 0 :(得分:5)

在模数逻辑中,结果值应该是得到0的余数。因此,当你说-3%26时,结果是-3,加上3得到0。

答案 1 :(得分:2)

数学家通常在整数a整数b除以a - bq时定义余数,其中商qfloor(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)