使用 unsigned int 时模数结果错误
Wrong modulus result when using unsigned int
我会考虑以下代码段:
int a =-9;
int m = 10;
unsigned int m1 =10;
std::cout<<a%m<<std::endl;
std::cout<<a%m1<<std::endl;
结果是:
-9
7
7太奇怪了。
谁能解释一下?
根据 C++ 2017(草案 n4659)8 11,对 a % m
的操作数执行通常的算术转换。根据 11.5.3,当一个操作数具有有符号整数类型而另一个具有大于或等于等级的无符号整数类型时,有符号操作数将转换为无符号操作数的类型。
这会导致 −9 的 int
值转换为 unsigned
。此转换执行的模数大于 unsigned
的最大值,在您的实现中显然是 4,294,967,295 (232−1),因此转换执行模数 4,294,967,296,这产生 4,294,967,287。 (执行对 4,294,967,296 取模的转换意味着根据需要多次添加或减去 4,294,967,296 以产生 0 到 4,294,967,295 范围内的结果,包括端值。)
然后%
运算符按照通常的方式运行; 4,294,967,287 除以 10 的余数是 7.
我会考虑以下代码段:
int a =-9;
int m = 10;
unsigned int m1 =10;
std::cout<<a%m<<std::endl;
std::cout<<a%m1<<std::endl;
结果是:
-9
7
7太奇怪了。 谁能解释一下?
根据 C++ 2017(草案 n4659)8 11,对 a % m
的操作数执行通常的算术转换。根据 11.5.3,当一个操作数具有有符号整数类型而另一个具有大于或等于等级的无符号整数类型时,有符号操作数将转换为无符号操作数的类型。
这会导致 −9 的 int
值转换为 unsigned
。此转换执行的模数大于 unsigned
的最大值,在您的实现中显然是 4,294,967,295 (232−1),因此转换执行模数 4,294,967,296,这产生 4,294,967,287。 (执行对 4,294,967,296 取模的转换意味着根据需要多次添加或减去 4,294,967,296 以产生 0 到 4,294,967,295 范围内的结果,包括端值。)
然后%
运算符按照通常的方式运行; 4,294,967,287 除以 10 的余数是 7.