Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带负红利和除数的C模运算差是长无符号的_C_Modulo - Fatal编程技术网

带负红利和除数的C模运算差是长无符号的

带负红利和除数的C模运算差是长无符号的,c,modulo,C,Modulo,嗨,我知道在C中,负除数的模会产生负模,但我发现,使用长无符号除数或长无符号除数的负除数的模会产生正模 下面是一个例子: #include <stdio.h> int main(int argc, char** argv) { long long int a = -2205348223670655684LL; printf("%lld %lld %lld %lld %lld %lld\n", a % 20, a % 20L, a % 20LL, a % 20U, a

嗨,我知道在
C
中,负除数的
会产生负模,但我发现,使用长无符号除数或长无符号除数的负除数的模会产生正模

下面是一个例子:

#include <stdio.h>

int main(int argc, char** argv)
{
    long long int a = -2205348223670655684LL;
    printf("%lld %lld %lld %lld %lld %lld\n", a % 20, a % 20L, a % 20LL, a % 20U, a % 20LU, a % 20LLU);
    return 0;
}

有人能解释为什么吗?我已经在GCC 4.8和5.1中尝试过了,C99第6.5.5/6节要求当a/b可表示时:

(a/b)*b+a%b应等于a

从6.5.5/3开始

通常的算术转换是在操作数上执行的

有关算术转换的更多详细信息,请参阅第6.3.1.8节

现在,它似乎出现在您的实现中
sizeof(long)=sizeof(long-long)=64位

对于前4种情况,有符号或无符号除数可以更改为分子类型(即
long long int
),但在后2种情况下,必须将除数更改为无符号类型(强制转换或重新解释为),因为除数具有相同的宽度且无符号导致结果


在某些系统上,如果
sizeof(long)
,则倒数第二个结果应该不同。

不存在使用一个有符号和一个无符号操作数执行的(内置)算术运算;二元运算的两个操作数升级为同一类型


在最后两个示例中,该类型为
无符号long-long
;因此,
a
被转换成一个无符号值,余数是用它来计算的。

“负红利的模导致负模”是错误的。这是实现定义的。@n.m。。。在早期的C标准中。我也知道在C11之前的标准中,带负号的模是特定于实现的,但无论如何,我也对实现的原理感兴趣,我在当前的标准中找不到任何解释这种行为的东西。请看这个线程@DevSolar N1570 6.5.5.6:"... 如果商a/b是可表示的,则表达式(a/b)*b+a%b应等于a;否则,a/b和a%b的行为都未定义。“
$> ./a.out
-4 -4 -4 -4 12 12