tôi đã gặp phải lỗi trong một số mã c tôi đã viết và trong khi tương đối dễ sửa, tôi muốn có thể hiểu vấn đề cơ bản tốt hơn. về cơ bản những gì đã xảy ra là tôi có hai số nguyên không dấu (uint32_t, trên thực tế), khi hoạt động mô đun được áp dụng, mang lại số tương đương chưa ký của một số âm, một số đã được bọc và do đó "lớn". đây là một chương trình ví dụ để chứng minh:tràn chưa được ký với toán tử mô-đun trong 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;
}
này xuất ra như sau, trên máy x86_64 của tôi:
-1
4294967295
18446744073709551104
-512
1536
2047
1536 là số tôi đã mong đợi, nhưng (uint32_t) (- 512) là số tôi đã nhận được, mà, như bạn có thể tưởng tượng, đã ném những thứ ra một chút.
vì vậy, tôi đoán câu hỏi của tôi là: tại sao hoạt động mô-đun giữa hai số không dấu, trong trường hợp này, tạo ra số lớn hơn số chia (nghĩa là số âm)? có lý do nào khiến hành vi này được ưa thích hơn không?
2600000000 là một int (hoặc có thể là 64-bit int - dài hoặc dài dài), mà có thể đã gây ra kết quả của phép nhân để trở thành một (ký) dài. Bạn đang sử dụng nền tảng nào? – Random832