Java Mod的语法是什么


231

以伪代码为例:

if ((a mod 2) == 0)
{
    isEven = true;
}
else
{
    isEven = false;
}

Answers:


357

对于非负整数,可以使用余数运算符来代替语义略有不同的取模运算符%。对于您的确切示例:

if ((a % 2) == 0)
{
    isEven = true;
}
else
{
    isEven = false;
}

可以简化为单线:

isEven = (a % 2) == 0;

80
if / else不必要,只需使用isEven =(a%2)== 0,
Steve Kuo 2010年

59
注意术语“ mod”和“ modular”,因为n(mod m)总是> = 0,但不是n%m。n%m在> -m和<m的范围内。尽管Java对int和long类型具有余数运算符,但它没有模数函数或运算符。即,-12%10 = -2,而-12 mod 10 =8。如果%运算符为n%m返回负值,则(n%m)+ m将得到n mod m。BigInteger提供了两种功能,它们的规格很好地说明了差异。另外,请注意零。在数学中,零是偶数,但不是正数或负数。
吉姆(Jim)

4
@ nl-x可能是因为明确优先级比保留优先级更好。%在查询==之前,我还不知道该值是多少,因此不清楚该表达式是否等于(a%2)==0a%(2==0)。我猜这在Java中布尔值与整数不同的情况下不太重要
Matthew Sainsbury 2014年

8
这不是模数运算符,而是余数运算符。请更正帖子!
基林·约翰斯通

2
布尔偶数=(((a&1)== 0)。容易得多。
mdev

111

这是用最少的Java代码表示的伪代码;

boolean isEven = a % 2 == 0;

我现在将其分解为各个部分。Java中的模运算符是百分比字符(%)。因此,采用int%int会返回另一个int。双重等于(==)运算符用于比较值,例如一对整数,并返回布尔值。然后将其分配给布尔变量“ isEven”。基于运算符的优先级,将在比较之前评估模量。


12
最小将没有括号;)
pstanton

3
它是余数运算符,而不是模数运算符。
罗恩侯爵,

@ user207421它的名字,其实是余数运算符但不等同他们:“ 模数 - 4 (计算,编程)操作员放在两个数字之间,要获得这些数字的余数。”?
GeroldBroser恢复了莫妮卡的

93

由于其他所有人都已经给出了答案,因此我将添加一些其他上下文。%“模数”运算符实际上正在执行余数运算。mod和rem之间的区别很小,但很重要。

(-1 mod 2)通常会给出1。更具体地说,给定两个整数X和Y,操作(X mod Y)倾向于返回[0,Y)范围内的值。换句话说,X和Y的模量始终大于或等于零且小于Y。

使用“%”或rem运算符执行相同的操作将保持X值的符号。如果X为负,则结果范围为(-Y,0];如果X为正,则结果范围为[0,Y)。

通常,这种微妙的区别并不重要。回到您的代码问题,但是,有多种解决“均匀性”的方法。

第一种方法特别适合初学者,因为它特别冗长。

// Option 1: Clearest way for beginners
boolean isEven;
if ((a % 2) == 0)
{
  isEven = true
}
else
{
  isEven = false
}

第二种方法更好地利用了该语言,并导致了更简洁的代码。(不要忘记==运算符返回一个布尔值。)

// Option 2: Clear, succinct, code
boolean isEven = ((a % 2) == 0);

这里的第三种方法是完整性的,它使用三元运算符。尽管三元运算符通常非常有用,但在这种情况下,我认为第二种方法更好。

// Option 3: Ternary operator
boolean isEven = ((a % 2) == 0) ? true : false;

第四种也是最后一种方法是使用整数二进制表示形式的知识。如果最低有效位为0,则数字为偶数。可以使用按位与运算符(&)进行检查。尽管此方法最快(您正在执行简单的位掩码而不是除法),但对于初学者来说可能有点高级/复杂。

// Option 4: Bitwise-and
boolean isEven = ((a & 1) == 0);

在这里,我使用了按位与运算符,并以选项2中所示的简洁形式表示它。将其重写为选项1的形式(以及选项3的形式),供读者练习。;)

希望能有所帮助。


谢谢罗布。这种困惑给程序员解释了如何从模块化算术中实现具有数学属性的算法带来了巨大的困难。余数不是NOT模数,但是可以从余数中快速得出一个模数。
吉姆(Jim)

1
@TickledPink除了不能在Java中编译之外。
尤金·别列索夫斯基'19

33

要使Java的%(REM)操作像MOD一样适用于负X和正Y值,可以使用以下方法:

private int mod(int x, int y)
{
    int result = x % y;
    if (result < 0)
    {
        result += y;
    }
    return result;
}

或使用三元运算符(在某些情况下更短,但不可能或效率较低):

private int mod(int x, int y)
{
    int result = x % y;
    return result < 0? result + y : result;
}

12

Java实际上没有C那样的模运算符。Java中的%是余数运算符。在正整数上,它的工作方式与模数完全相同,但是在负整数上的工作方式不同,并且与模数不同,它也可以使用浮点数。尽管如此,在除正整数之外的任何东西上都很少使用%,因此,如果您想将它称为模数,那就放心吧!


但是我想要一个真正的模运算符,该运算符也适用于负整数,以便array[x mod array.length]始终访问数组中的元素,而不是尝试索引负位置。
克里斯,

2
(x % y + y) % y 或从Java 8开始Math.floorMod(x, y)
Greg Charles

12

尽管可以通过检查值是否为负来进行适当的取模,然后将其校正为负(许多人建议的方式),但还有一个更紧凑的解决方案。

(a % b + b) % b

这将首先进行模运算,将值限制为-b-> + b范围,然后添加b以确保该值为正,让下一个模数将其限制为0-> b范围。

注意:如果b为负,结果也将为负


当a和b都为大数时,这可能会溢出,因此这不是正确的解决方案。
Trixie Wolf

11

该代码运行更快,无需使用模数:

public boolean isEven(int a){
    return ( (a & 1) == 0 );
}

public boolean isOdd(int a){
    return ( (a & 1) == 1 );
}

3
这看起来比接受的答案干净得多。这与过早的优化无关。如果工作正常,那就更好了。
AlexWien

4
@LluisMartinez这是计算中最被错误引用的谚语之一。完整的引文是:“程序员浪费大量时间来考虑或担心程序非关键部分的速度,而这些效率的尝试实际上在考虑调试和维护时会产生严重的负面影响。我们应该忽略一些小问题。大约有97%的效率是效率:过早的优化是万恶之源,但我们不应该在这3%的临界水平上放弃机会。” 这实际上意味着完全不同的东西。
洛恩侯爵,2015年

3
@EJP你可能是对的。我做了一个测试(循环一百万次),取模为4000纳秒,逻辑与为2500纳秒。
Lluis Martinez

为什么这是答案?当然,它的确是偶数,但对于mod / remainder运算符不起作用。问题是关于mod运算符,而不是如何找到奇数。
Mark Walsh



4

在Java中,它是%运算符: 15.17.3。余算符%

请注意,floorModjava.lang.Math类中也将提供%与带不同符号的参数不同的结果:

public static int floorMod​(int x, int y)


1
赞成使用,因为floorMod是一个更好的“模”运算符,%因为它在参数为负数时也可以正常工作。其他答案中没有一个是真正正确的,因为它们带有以下声明:除非参数为正数,否则%不是真正的模数。特别是如果您想将每个整数映射到数组中的连续位置,那么array[floorMod(i, array.length)即使索引i进入负数区域也可以正常工作。并非如此%
克里斯,

3

另外,mod可以这样使用:

int a = 7;
b = a % 2;

b等于1。因为7 % 2 = 1


对于初学者来说,在没有输出的情况下使用复合运算符可能是一个错误。
Stu Thompson

3

Java中的余数运算符是%,模运算符可以表示为

public int mod(int i, int j)
{
  int rem = i % j;
  if (j < 0 && rem > 0)
  {
    return rem + j;
  }
  if (j > 0 && rem < 0)
  {
    return rem + j;
  }
  return rem;
}

2

正如其他人指出的那样,%(余数)运算符与数学 mod模运算/函数不同。

mod%

x mod n函数映射xn范围内[0,n)
x % n运算符映射xn的范围(-n,n)

为了拥有一种使用数学模运算而不关心前面符号的方法,x可以使用:

((x % n) + n) % n

也许这张照片有助于更好地理解它(我很难把头放在这上面)

在此处输入图片说明


1
漂亮的图画。另一种复杂性:这并未考虑int变量本身的2 ^ 32模块化。该floorMod方法可以正确执行此操作(但是如果n为负,则可能需要其他计算)。
Maarten Bodewes

1

另一种方法是:

boolean isEven = false;
if((a % 2) == 0)
{
    isEven = true;
}

但最简单的方法仍然是:

boolean isEven = (a % 2) == 0;

就像@Steve Kuo所说的那样。


0

在中Java,可以按以下方式执行mod操作:

Math.floorMod(a, b)

注:MOD操作是从不同的其余操作。在中Java其余操作可以这样执行:

a % b

好吧,不完全是...的javadoc Math.floorMod()拥有它:The floor modulus is x - (floorDiv(x, y) * y), has the same sign as the divisor y, and is in the range of -abs(y) < r < +abs(y).因此它与数学模数不完全相同。但是,用相同的方法在Javadoc中也有一种获得肯定结果的方法:If the signs of arguments are unknown and a positive modulus is needed it can be computed as (floorMod(x, y) + abs(y)) % abs(y).
WesternGun

@WesternGun可能是正确的,但是如果您知道模数为正,则该floorMod操作将按预期进行。还有floorModfor long值,否则有BigInteger更大的值。
Maarten Bodewes

-1

模运算符为%(百分号)。要测试均匀性或通常对2的幂进行模运算,还可以使用&(the和运算符),例如isEven =!(a&1)。


-3

@Cody的代码的替代方法:

使用模运算符:

bool isEven = (a % 2) == 0;

我认为这比编写if / else稍好一些,因为重复和未使用的灵活性更少。检查确实需要更多的脑力,但是isEven补偿的命名很不错。


2
它是余数运算符,而不是模数运算符。
罗恩侯爵

@EJP好的。那么什么是模运算符?
TheRealChx101 '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.