为什么Java的%运算符给出的结果与我的计算器的结果不同?
怎么来计算器-1 mod 26 = 25,但在C或Java -1 % 26 == -1
。 我需要一个像计算器一样解决它的程序。 这两者有区别吗?
两个答案(25和-1)都有效。 只是不同的系统有不同的约定。
我认为最常见的(数学)是:
quotient = floor(x / y) remainder = x - quotient * y
floor()
是向负无穷大舍入的地方。
这是您的计算器给您的约定。 (Mathematica也使用这个惯例。)
我认为大多数编程语言使用的是:
quotient = integerpart(x / y) remainder = x - quotient * y
其中integerpart()
与(float – > integer) integerpart()
相同。 (向零舍入)
有些惯例喜欢将余数保持为与其中一个操作数相同的符号。
同样的事情适用于分隔符的符号。 不同的惯例是不同的。
“怎么会 … ?”
模运算有两种常见的定义。 Java选择了一个(“与分红相同的符号”),计算器实现了另一个; 可能是“与除数相同的符号”,尽管你需要做一些实验才能确定。
事实上, 模数操作的维基百科页面给出了不同编程语言使用的4种不同的运算符定义。 (有些编程语言为您提供了两个具有不同语义的运算符。)
对于C,定义取决于您所讨论的C标准的版本。 对于ISO C 1999,模运算符遵循与Java相同的定义。 对于C标准的早期版本, %
的语义是依赖于实现的
“两者之间有区别吗?”
显然有!
“我需要一个像计算器一样解决它的程序。”
随意写一个:-)。
但是如果你只是想知道如何在Java中获得与模数相同的“除数”forms,这里有一种方法:
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));
具有负操作数的模运算在不同语言中是不同的,并且取决于驱动的语言定义。 在Java中, Modulus更像是Remainder 。
通常,如果您想获得负输入的负数,那么您可以使用:
int r = x % n; if (r > 0 && x < 0) { r -= n; }
或者,如果您使用的语言在负输入上返回负数,则您更愿意为正:
int r = x % n; if (r < 0) { r += n; }
因此,根据您所需的结果,我建议您使用适当的实现,而不是依靠语言为您计算。
此外,请注意,在JLS中,在15.17.3 - 剩余运算符% 部分中对Java的结果进行了详细描述。 他们给出了一个动机(%b应该是这样的(a / b)* b +(a%b)等于a)但是在JLS中包含该部分会产生结果。