0

假设我有(-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);
}

输出

在此处输入图像描述

4

4 回答 4

6

%运算符被视为余数运算符,因此结果的符号与被除数的符号相同。

如果你想要一个模函数,你可以这样做:

int mod(int a, int b)
{
    int ret = a % b;
    if (ret < 0)
        ret += b;
    return ret;
}
于 2017-05-13T12:45:01.400 回答
2

为什么会这样?

在 C 中以这种方式定义的 %是余数运算符。根据6.5.5 乘法运算符, C 标准的第 6 段:

当整数被除法时,/运算符的结果是代数商,其中任何小数部分被丢弃。如果商a/b是可表示的,则表达式(a/b)*b + a%b 应等于a;否则,两者的行为a/ba%b是未定义的。

它在 Java 中也是这样定义的。根据15.17.3。Java 8 规范的数运算符百分比

据说二进制 % 运算符从隐含的除法中产生其操作数的其余部分;左边的操作数是被除数,右边的操作数是除数。

在 C 和 C++ 中,余数运算符只接受整数操作数,但在 Java 编程语言中,它也接受浮点操作数。

在二进制数值提升(第 5.6.2 节)之后,整数操作数的余数运算产生一个结果值,使得 (a/b)*b+(a%b) 等于 a。

即使在被除数是其类型的最大可能量级的负整数并且除数是-1(余数是0)的特殊情况下,这个恒等式也成立。

由这个规则得出,余数运算的结果只有当被除数为负时才能为负,只有当被除数为正时才能为正。此外,结果的大小总是小于除数的大小。

所以余数 -%运算符的结果 - 必须与被除数具有相同的符号 -%运算符之前的第一个值。

于 2017-05-13T12:51:40.353 回答
0

你应该看看 Stack Overflow 问题“mod”和“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不考虑符号(使答案的大小小于除数的大小),如果答案是否定的,则将除数添加到其中。

于 2017-05-13T12:54:42.730 回答
-1

这与数字是负数还是正数无关。5%8会返回5,因为这就是mod运营商的工作方式。

如果你想要3-3作为结果,你需要分别做8%5-8%5

这是文档,这就是它所说的:

将一个操作数除以另一个并返回余数作为结果。

所以,它总是 fir 操作数除以秒。此外,如果你想要积极的结果,那么你可以这样做:

Math.abs(-8%5);
于 2017-05-13T12:43:18.407 回答