java如何用负数做模数计算?

我做模数错了吗? 因为在Java中-13 % 64应该被评估为-13但是我得到了51

负数模数的两个定义都在使用 – 有些语言使用一个定义,另一个使用另一个定义。

如果你想得到一个负数的负数input,那么你可以使用这个:

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

同样,如果您使用的是一种在负面input中返回负数的语言,您更愿意使用正数:

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

由于“math”都是正确的:

 -13 % 64 = -13 (on modulus 64) -13 % 64 = 51 (on modulus 64) 

其中一个选项必须由Java语言开发人员select,他们select了:

结果的标志等于股息的标志。

在Java规范中说:

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3

你确定你在使用Java吗? 因为Java按预期给出-13%64 = -13。 股息的标志!

Java的结果是错误的。 请提供一些背景知识(Java程序,实现和版本)。

从Java语言规范

15.17.3剩余操作员%
[…]
二进制数字提升(§5.6.2)之后的整数操作数的其余操作会生成一个结果值,使得(a / b)* b +(a%b)等于a。

15.17.2司司长/
[…]
整数部分向0

由于/向零舍入(导致为零),在这种情况下%的结果应该是负的。

您可以使用

 (x % n) - (x < 0 ? n : 0); 

你的答案是在维基百科: 模操作

它说,在Java中,模运算的符号与红利的符号相同。 因为我们正在谈论的其余部门的操作就好了,它返回-13在你的情况下,因为-13 / 64 = 0.13-0 = -13。

编辑:对不起,误解了你的问题…你说得对,Java应该给-13。 你能提供更多的周边代码吗?

具有负操作数的模运算由语言devise者定义,他可能会将其留给语言实现,他们可能会将定义推迟到CPU架构。

我无法findJava语言定义。
感谢Ishtar, 剩余操作符的 Java语言规范%表示结果的符号与分子的符号相同。

在模数m 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的余数。

为了克服这个问题,你可以把64 (或者任何你的模数基数)加到负值,直到它是正值

 int k = -13; int modbase = 64; while (k < 0) { k += modbase; } int result = k % modbase; 

结果仍然是在相同的等价类。

mod函数被定义为数字超过除数的最大整数倍的数量。 所以在你的情况下

 -13 % 64 

不超过-13的64的最大整数倍是-64。 现在,当从-64减去-13时,它等于51 -13 - (-64) = -13 + 64 = 51

在我的Java JDK版本1.8.0_05 -13%64 = -13

你可以尝试使用-13-(int(-13/64))换句话说,除法转换为整数以除掉小数部分,然后从分子中减去因此分子 – (int(分子/分母))应该给出正确的剩余和标志

在Java最新版本中你会得到-13%64 = -13 。 答案总会有分子的标志。

根据JLS第15.17.3节的规定,“二进制数字提升后的整数操作数的余数运算产生一个结果值,使得(a / b)* b +(a%b)等于a。在特殊情况下,股利是其types的最大可能幅度的负整数,除数是-1(余数为0)“。

希望有所帮助。

在这种情况下,我不认为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); } }