我需要在 C 中执行一个真正的数学模运算。对我来说允许模块参数为负数是有意义的,因为我的模块计算可以产生负中间结果,必须将其放回最少残差系统。但是允许否定模块是没有意义的,因此我写了

unsigned int mod( int x, unsigned int m )
{
    int r = x % m;
    return r >= 0 ? r : r + m;
}

但是用负数和正模块调用这样的函数
printf("%u\n", mod(-3, 11));

产生输出
1

我不明白为什么。你能解释一下吗?

编辑:我知道运算符 % 与数学模不同,我知道它是如何为正数和负数定义的。我在问它对不同的符号会做什么,而不是不同的符号。

最佳答案

启用 clang-Wconversion 清楚地指出了你的错误:

prog.cc:3:15: warning: implicit conversion changes signedness: 'unsigned int' to 'int' [-Wsign-conversion]
    int r = x % m;
        ~   ~~^~~
prog.cc:3:13: warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-Wsign-conversion]
    int r = x % m;
            ^ ~
prog.cc:4:21: warning: operand of ? changes signedness: 'int' to 'unsigned int' [-Wsign-conversion]
    return r >= 0 ? r : r + m;
    ~~~~~~          ^
prog.cc:4:25: warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-Wsign-conversion]
    return r >= 0 ? r : r + m;
                        ^ ~
prog.cc:9:12: warning: implicit conversion changes signedness: 'unsigned int' to 'int' [-Wsign-conversion]
    return mod(-3, 11);
    ~~~~~~ ^~~~~~~~~~~

live example on wandbox

当转换为 unsigned int 时, -3 变为 4294967293
4294967293 % 11 等于 1

10-06 09:37