我做模数错了吗?因为在Java中-13 % 64
应该评估为-13
,但我得到51
。
答案 0 :(得分:98)
负数模数的两个定义都在使用中 - 有些语言使用一个定义,另一些使用另一个定义。
如果您想获得负输入的负数,那么您可以使用:
int r = x % n;
if (r > 0 && x < 0)
{
r -= n;
}
同样,如果你使用的语言在负面输入上返回负数,你会更喜欢肯定:
int r = x % n;
if (r < 0)
{
r += n;
}
答案 1 :(得分:69)
由于“数学上”两者都是正确的:
-13 % 64 = -13 (on modulus 64)
-13 % 64 = 51 (on modulus 64)
其中一个选项必须由Java语言开发人员选择,他们选择:
结果的符号等于股息的符号。
在Java规范中说:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3
答案 2 :(得分:19)
你确定你在使用Java吗? '因为Java按预期给出-13%64 = -13。分红的标志!
答案 3 :(得分:14)
您的结果对Java来说是错误的。 请提供一些上下文(您的程序,实现和Java版本)。
15.17.3剩余运营商%
[...]
二进制数字提升(第5.6.2节)后整数操作数的余数运算产生一个结果值,使得(a / b)* b +(a%b)等于a。
15.17.2分部操作员/
[...]
整数除法向0舍入。
由于/被舍入为零(导致为零),因此在这种情况下%的结果应为负。
答案 4 :(得分:5)
你可以使用
(x % n) - (x < 0 ? n : 0);
答案 5 :(得分:3)
您的答案在维基百科: modulo operation
它说,在Java中,模运算的符号与被除数的符号相同。因为我们正在谈论除法运算的其余部分就好了,在你的情况下它会返回-13,因为-13/64 = 0. -13-0 = -13。
编辑:对不起,误解了你的问题...你是对的,java应该给-13。你能提供更多周边代码吗?答案 6 :(得分:2)
具有负操作数的模运算由语言设计者定义,语言设计者可能将其留给语言实现,后者可能将定义推迟到CPU体系结构。
我无法找到Java语言定义。
感谢Ishtar,Remainder Operator %的Java语言规范说结果的符号与分子的符号相同。
答案 7 :(得分:1)
x = x + m = x - m
中的 m
因此模数-13 = -13 + 64
中的64
和模数-13 = 51
中的64
假设Z = X * d + r
,如果0 < r < X
,则在Z/X
分区,我们会将r
称为余数。
Z % X
返回Z/X
的剩余部分。
答案 8 :(得分:1)
要解决此问题,您可以将64
(或任何模数基数)添加到负值,直到它为正
int k = -13;
int modbase = 64;
while (k < 0) {
k += modbase;
}
int result = k % modbase;
结果仍然在同一个等价类中。
答案 9 :(得分:1)
mod函数定义为数字超过除数的最大整数倍的数量,该除数不大于该数。所以在你的情况下
-13 % 64
64的最大整数倍,不超过-13是-64。现在,当你从-64减去-13时,它等于51 -13 - (-64) = -13 + 64 = 51
答案 10 :(得分:0)
在我的Java JDK版本1.8.0_05 -13%64 = -13
中你可以尝试-13-(int(-13/64)) 换句话说,将除法转换为整数以除去小数部分 然后从分子中减去 因此,分子 - (int(分子/分母))应该给出正确的余数&amp;登录
答案 11 :(得分:0)
在Java最新版本中,您获得-13%64 = -13
。答案总会有分子的迹象。
答案 12 :(得分:0)
根据JLS的第15.17.3节,“二进制数字提升后整数操作数的余数运算产生的结果值使得(a / b)* b +(a%b)等于a。 即使在特殊情况下,这种身份仍然存在,即被除数是其类型的最大可能量值的负整数,除数为-1(余数为0)。“
希望有所帮助。
答案 13 :(得分:-1)
在这种情况下,我认为Java不会返回51。我在Mac上运行Java 8,然后得到:
-13 % 64 = -13
程序:
public class Test {
public static void main(String[] args) {
int i = -13;
int j = 64;
System.out.println(i % j);
}
}