java如何用负数进行模数计算?

Jak*_*r00 89 java math modulo negative-number

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

Mar*_*ers 99

负数模数的两个定义都在使用 - 一些语言使用一个定义而另一个定义使用另一个定义.

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

int r = x % n;
if (r > 0 && x < 0)
{
    r -= n;
}
Run Code Online (Sandbox Code Playgroud)

同样,如果您使用的语言在负面输入上返回负数,您会更喜欢正面:

int r = x % n;
if (r < 0)
{
    r += n;
}
Run Code Online (Sandbox Code Playgroud)

  • 在Java中,负模数不会改变任何东西,如果你使用Abs(),只需写r = x%abs(n).我不喜欢if语句,我宁愿写r =((x%n)+ n)%n.关于2模(2,4,8,16等)的幂和正答案,考虑二元掩模r = x&63. (5认同)
  • 如果n为负,则这不起作用.如果您使用Java 7 Lang Spec(第15.17.3节)中的相同示例:( - 5)%( - 3)= -2.添加-3将无效.如果要确保值为正,则应添加n的绝对值. (3认同)
  • 在Java的上下文中(根据问题标签),这个答案本质上是"错误的".给定表达式"x%y",A)如果"x"为负,则余数为负,即"x%y == - ( - x%y)".B)'y`的符号没有效果,即`x%y == x%-y` (3认同)

Can*_*ner 70

由于"数学上"两者都是正确的:

-13 % 64 = -13 (on modulus 64)  
-13 % 64 = 51 (on modulus 64)
Run Code Online (Sandbox Code Playgroud)

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

结果的符号等于股息的符号.

在Java规范中说:

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

  • 问题是"当我期待`-13`时,为什么Java给我'-13%64 = 51`?". (8认同)
  • Java 8中提供了数学上理智的行为:[Math.floorMod](https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floorMod-int-int-) (8认同)
  • @pascal:java为您提供了正确的数学定义以及实现它的方式,而不是您期望的那样. (5认同)

小智 20

你确定你在使用Java吗?'因为Java按预期给出-13%64 = -13.分红的标志!


sta*_*lue 15

你的结果对Java来说是错误的.请提供一些上下文(您的程序,实现和Java版本).

来自Java语言规范

15.17.3剩余运算符%
[...]
二进制数字提升(第5.6.2节)后整数操作数的余数运算产生的结果值使得(a/b)*b +(a%b)等于一个.
15.17.2除法运算符/
[...]
整数除法向0 舍入.

由于/被舍入为零(导致为零),因此在这种情况下%的结果应为负.


rus*_*lik 5

您可以使用

(x % n) - (x < 0 ? n : 0);
Run Code Online (Sandbox Code Playgroud)

  • @ruslik 你也可以这样做:`((x % k) + k) % k`。(虽然你的可能更具可读性。) (3认同)
  • @JohnKurlak 你的版本是这样工作的:4 % 3 = 1 OR 4 % -3 = -2 OR -4 % 3 = 2 OR -4 % -3 = -1 但来自 ruslik 的版本是这样的:4 % 3 = 1 或 4 % -3 = 1 或 -4 % 3 = -4 或 -4 % -3 = 2 (2认同)