Mod 与负数在 Java 和 C 中给出负结果
Mod with negative numbers gives a negative result in Java and C
假设我有 (-5) mod 8
.
我在 Java 和 C 两种语言中都尝试过,他们给了我一个 -5
结果,而我期待 3
.
为什么会这样?模数可以为负吗?我应该更改什么以获得正确的结果?
Java代码
public class Example {
public static void main(String[] args) {
int x;
x = -5%8;
System.out.println(x);
}
}
C代码
int main(){
int x;
x = -5%8;
printf("%d", x);
}
输出
这与数字是负数还是正数无关。 5%8
会 return 5
因为这就是 mod
运算符的工作方式。
如果你想要3
或-3
结果,你需要分别做8%5
或-8%5
。
Here's 文档,是这样说的:
divides one operand by another and returns the remainder as its
result.
所以,它总是第一个操作数除以第二个。另外,如果你想要积极的结果,那么你可以这样做:
Math.abs(-8%5);
%
运算符被当作余数运算符处理,所以结果的符号与被除数的符号相同。
如果你想要模函数,你可以这样做:
int mod(int a, int b)
{
int ret = a % b;
if (ret < 0)
ret += b;
return ret;
}
Why is this happening?
C语言中就是这样定义的。%
是取余运算符。根据 6.5.5 乘法运算符,the C Standard 的第 6 段:
When integers are divided, the result of the /
operator is the
algebraic quotient with any fractional part discarded. If the
quotient a/b
is representable, the expression (a/b)*b + a%b
shall equal a
; otherwise, the behavior of both a/b
and
a%b
is undefined.
在Java中也是这样定义的。根据 15.17.3。 the Java 8 specification 的余数运算符 %:
The binary % operator is said to yield the remainder of its operands
from an implied division; the left-hand operand is the dividend and
the right-hand operand is the divisor.
In C and C++, the remainder operator accepts only integral operands,
but in the Java programming language, it also accepts floating-point
operands.
The remainder operation for operands that are integers after binary
numeric promotion (§5.6.2) produces a result value such that
(a/b)*b+(a%b) is equal to a.
This identity holds even in the special case that the dividend is the
negative integer of largest possible magnitude for its type and the
divisor is -1 (the remainder is 0).
It follows from this rule that the result of the remainder operation can be negative only if the dividend is negative, and can be positive
only if the dividend is positive. Moreover, the magnitude of the
result is always less than the magnitude of the divisor.
因此余数 - %
运算符的结果 - 必须与被除数 - %
运算符之前的第一个值具有相同的符号。
你应该看看 Stack Overflow 问题 What's the difference between “mod” and “remainder”?。
要获得mod积极的做-
C代码-
int main(){
int a, b;
scanf("%d %d", &a, &b);
int rem = a%b;
if (rem<0)
rem += b;
printf("%d", rem);
return 0;
}
类似的是 Java 代码。
基本上,方法是先取 mod
,不管符号如何(使答案的大小小于除数的大小),如果答案是否定的,则加上除数。
假设我有 (-5) mod 8
.
我在 Java 和 C 两种语言中都尝试过,他们给了我一个 -5
结果,而我期待 3
.
为什么会这样?模数可以为负吗?我应该更改什么以获得正确的结果?
Java代码
public class Example {
public static void main(String[] args) {
int x;
x = -5%8;
System.out.println(x);
}
}
C代码
int main(){
int x;
x = -5%8;
printf("%d", x);
}
输出
这与数字是负数还是正数无关。 5%8
会 return 5
因为这就是 mod
运算符的工作方式。
如果你想要3
或-3
结果,你需要分别做8%5
或-8%5
。
Here's 文档,是这样说的:
divides one operand by another and returns the remainder as its result.
所以,它总是第一个操作数除以第二个。另外,如果你想要积极的结果,那么你可以这样做:
Math.abs(-8%5);
%
运算符被当作余数运算符处理,所以结果的符号与被除数的符号相同。
如果你想要模函数,你可以这样做:
int mod(int a, int b)
{
int ret = a % b;
if (ret < 0)
ret += b;
return ret;
}
Why is this happening?
C语言中就是这样定义的。%
是取余运算符。根据 6.5.5 乘法运算符,the C Standard 的第 6 段:
When integers are divided, the result of the
/
operator is the algebraic quotient with any fractional part discarded. If the quotienta/b
is representable, the expression(a/b)*b + a%b
shall equala
; otherwise, the behavior of botha/b
anda%b
is undefined.
在Java中也是这样定义的。根据 15.17.3。 the Java 8 specification 的余数运算符 %:
The binary % operator is said to yield the remainder of its operands from an implied division; the left-hand operand is the dividend and the right-hand operand is the divisor.
In C and C++, the remainder operator accepts only integral operands, but in the Java programming language, it also accepts floating-point operands.
The remainder operation for operands that are integers after binary numeric promotion (§5.6.2) produces a result value such that (a/b)*b+(a%b) is equal to a.
This identity holds even in the special case that the dividend is the negative integer of largest possible magnitude for its type and the divisor is -1 (the remainder is 0).
It follows from this rule that the result of the remainder operation can be negative only if the dividend is negative, and can be positive only if the dividend is positive. Moreover, the magnitude of the result is always less than the magnitude of the divisor.
因此余数 - %
运算符的结果 - 必须与被除数 - %
运算符之前的第一个值具有相同的符号。
你应该看看 Stack Overflow 问题 What's the difference between “mod” and “remainder”?。
要获得mod积极的做-
C代码-
int main(){
int a, b;
scanf("%d %d", &a, &b);
int rem = a%b;
if (rem<0)
rem += b;
printf("%d", rem);
return 0;
}
类似的是 Java 代码。
基本上,方法是先取 mod
,不管符号如何(使答案的大小小于除数的大小),如果答案是否定的,则加上除数。