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); } }