Я экспериментирую как с типами данных unsigned int, так и с параметрами основных методов в простых программах на C. В качестве эксперимента я написал программу, которая берет число int из командной строки в качестве параметра основного метода и суммирует каждое целое число между этим числом и 0.
Например. Программа вычисляет f (n) = (1 + 2 + 3 ... + n), допустимое, когда n> 0.
#include <stdio.h>
#include <stdlib.h>
const unsigned int MAX_NUM = 92681; //Max input that will avoid int overflow later on
unsigned int sum(unsigned int x);
int main(int argc, char *argv[]) {
unsigned int input = atoi(argv[1]);
if (input < 0 || input > MAX_NUM) {
printf("Invalid input! Input must be less than 92682\n");
exit(0); //If input > MAX_NUM, quit program
}
unsigned int result = sum(input);
printf("Sum to %d = %d\n", input, result);
return 0;
}
unsigned int sum(unsigned int x) {
unsigned int sum = 0;
unsigned int y;
for (y = 0; y <= x; y++) {
sum += y;
printf("Current sum:\t%u\n",sum);
}
return sum;
}
Первое, что я начал замечать, это целочисленное переполнение, когда f (n)> 2147483648 - то есть максимальное значение для подписанного int.
Я вручную вычислил максимальные значения, для которых результаты, сгенерированные моей программой, будут действительными (например, до переполнения целых чисел), равными 65535 для целых чисел со знаком и 92681 для целых чисел без знака.
Выполнение программы для подписанных целых чисел дало ожидаемые результаты - на 65535 очень большое положительное число превратилось в очень большое отрицательное число, поскольку целое число переполнилось.
Затем я прошел и изменил каждое «int» на «unsigned int». Несмотря на это целочисленное переполнение происходит, как если бы целые числа были подписаны, а не беззнаковые.
У меня вопрос а) Почему это? б) Как я могу сделать так, чтобы мой ответ мог использовать весь диапазон unsigned int, то есть от 0 до (2 ^ 32) - 1 (поскольку мне не нужны отрицательные значения!).
Большое спасибо!