为什么Java的%运算符给出的结果与我的计算器的结果不同?

时间:2011-09-20 02:45:26

标签: java c math modulus

如何计算器-1 mod 26 = 25,但是在C或Java -1 % 26 == -1中。我需要一个像计算器一样解决它的程序。两者之间有区别吗?

3 个答案:

答案 0 :(得分:6)

两个答案(25和-1)都有效。只是不同的系统有不同的约定。

我认为最常见的(数学)是:

quotient  = floor(x / y)
remainder = x - quotient * y

floor()向负无穷大方向前进。

这是您的计算器给您的惯例。 (Mathematica也使用这个惯例。)

我认为大多数编程语言使用的是:

quotient  = integerpart(x / y)
remainder = x - quotient * y

其中integerpart()与(float - >整数)强制转换相同。 (向零舍入)

有些惯例要保持余数与其中一个操作数相同。

同样的事情适用于分隔符的符号。不同的惯例是不同的。

答案 1 :(得分:5)

  

“怎么来......?”

模运算有两种常见的定义。 Java选择了一个(“与分红相同的符号”),计算器实现另一个;可能是“与除数相同的符号”,尽管你需要做一些实验才能确定。

事实上,modulo operation上的维基百科页面给出了不同编程语言使用的4种不同的运算符定义。 (并且一些编程语言为您提供了两个具有不同语义的运算符。)

对于C,定义取决于您所谈论的C标准的版本。对于ISO C 1999,模运算符遵循与Java相同的定义。对于早期版本的C标准,%的语义依赖于实现

  

“两者之间有区别吗?”

显然有!

  

“我需要一个像计算器一样解决它的程序。”

随意写一个: - )。

但是如果你只是想知道如何在Java中获得与模数相同的“除数”形式,这里有一种方法:

int otherModulus = (a % b) + (a < 0 ? b : 0);  // works for b > 0.

int otherModulus = (a % b) +                   // works for b != 0
                   (b > 0 ? (a < 0 ? b : 0) : (a > 0 ? -b : 0));

答案 2 :(得分:3)

负操作数的模运算在不同的语言中是不同的,并且是驱动的语言定义。在Java中,模数更像是剩余

通常,如果您想获得负输入的负数,那么您可以使用:

int r = x % n;
if (r > 0 && x < 0)
{
    r -= n;
}

或者,如果您使用的语言在否定输入上返回负数,则您更愿意为正:

int r = x % n;
if (r < 0)
{
    r += n;
}

因此,根据您所需的结果,我建议您使用适当的实现,而不是依靠语言为您计算。

另外,请注意,在JLS: in the section 15.17.3 - 剩余运算符%中,以Java身份描述了结果应该是什么。他们给出了一个动机(%b应该是这样的(a / b)* b +(a%b)等于a)但是在JLS中包含该部分会产生结果。