我遇到了一些我編寫的c代碼中的錯誤,雖然它相對容易修復,但我希望能夠更好地理解它的基礎問題。基本上發生了什麼是我有兩個無符號整數(uint32_t,實際上),當應用模數運算時,產生了一個負數的無符號等價物,這個數是一個被包裝的數,因此是「大的」。這裏是一個例子程序來演示:無符號溢出模運算符C
#include <stdio.h>
#include <stdint.h>
int main(int argc, char* argv[]) {
uint32_t foo = -1;
uint32_t u = 2048;
uint64_t ul = 2048;
fprintf(stderr, "%d\n", foo);
fprintf(stderr, "%u\n", foo);
fprintf(stderr, "%lu\n", ((foo * 2600000000) % u));
fprintf(stderr, "%ld\n", ((foo * 2600000000) % u));
fprintf(stderr, "%lu\n", ((foo * 2600000000) % ul));
fprintf(stderr, "%lu\n", foo % ul);
return 0;
}
這產生以下輸出,我的x86_64的機器上:
-1
4294967295
18446744073709551104
-512
1536
2047
1536是我期待的數目,但(uint32_t的)( - 512)是我得到的這個數字,正如你所想象的那樣,這個數字會有所下降。
所以,我想我的問題是:爲什麼兩個無符號數之間的模操作,在這種情況下,產生了一些比除數(即負數)還大嗎?這種行爲是首選的原因嗎?
2600000000是一個int(或可能是一個64位int長或long long),這可能會導致乘法的結果成爲(signed)long。你在哪個平臺上? – Random832