Я столкнулся с ошибкой в некотором написанном мною коде C, и хотя его было относительно легко исправить, я хочу лучше понять проблему, лежащую в его основе.по сути, у меня было два целых числа без знака (фактически, uint32_t), которые, когда была применена операция модуля, дали беззнаковый эквивалент отрицательного числа, числа, которое было упаковано и, таким образом, было «большим».Вот пример программы для демонстрации:
#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) это число, которое я получал, которое, как вы можете себе представить, немного сбило все с толку.
так что, я думаю, мой вопрос заключается в следующем: почему в этом модуле происходит работа модуля между двумя числами без знака?случай, произвести число, которое больше делителя (то есть отрицательное число)?есть ли причина, по которой такое поведение предпочтительнее?