#c #printf #overflow
Вопрос:
У меня есть упражнение, которое выглядит так:
Напишите программу, чтобы найти наибольшее число, представленное типами данных short, int, long int и long long int.
Я решил это 3 способами, и я хотел бы использовать самый элегантный для меня, используя оператор сдвига. Но я не могу найти способ правильно распечатать вывод, потому что, когда я использую printf
форматирование числа, оно изменяет найденный мной результат и переходит в переполнение.
Не могли бы вы рассказать, как правильно распечатать окончательные результаты ? Почему преобразование меньшего типа в больший изменяет число ?
Я не понимаю, почему единственный, который оказывается правильным, — это тот, который для short
типа. Int
, long int
и long long int
продолжайте переполнять, несмотря на то, что объявление формата кажется мне правильным.
printf("Greatest short: %d n", (1 << sizeof(short) * 8) - 1);
printf("Greatest int: %i n", (1 << sizeof(int) * 8) - 1 ); //overflow
printf("Greatest long int: %li n", (long int) (1 << sizeof(long int) * 8) - 1 ); // overflow
printf("Greatest long int: %lli n", (long long int) (1 << sizeof(long long int) * 8) - 1 ); //overflow
Комментарии:
1. Вы превышаете максимальное значение подписанных значений.
Ответ №1:
Для дополнения двух максимальных положительных чисел вам нужно:
printf("Greatest short: %d n", (1 << (sizeof(short)) * CHAR_BIT) - 1);
printf("Greatest int: %i n", (1U << (sizeof(int) * CHAR_BIT - 1)) - 1);
printf("Greatest long int: %li n", (long int) ((1UL << (sizeof(long int) * CHAR_BIT - 1)) - 1));
printf("Greatest long long int: %lli n", (long long int) ((1ULL << (sizeof(long long int) * CHAR_BIT - 1)) - 1) );
Комментарии:
1. Не могли бы вы уточнить ? Я узнал , что
Char_bit
для систем posix== 8
это так, и в целом мы можем предположить, что архитектуры используют тип char в 8 битах. Почему число без знака должно быть2 ^ (number_of_bytes * number_bits - 1) -1
, а не2 ^ (number_of_bytes * number_bits) -1
должно быть ? Почему дополнительно-1
?2. Я также не очень хорошо понимаю разницу
1
1U
между, и т. Д. При выполнении оператора сдвига я понимаю, что буду перемещать 1 бит слева дляnumber_of_bytes*char_bit
позиций. Например, Могу ли я сказать, что для 4-разрядного числа операция1 << 4
«равносильна заполнению1111
«, плюс-1
, поскольку это будет последнее число перед переполнением (последний левый 1 будет переполнен)? Так почему же мне нужно указать, что эта 1 цифра равна1U
или1UL
? Можете ли вы объяснить, как работает побитовая операция в(1 << (sizeof(int) * CHAR_BIT - 1)) - 1)
VS(1U << (sizeof(int) * CHAR_BIT - 1)) - 1)
(примечание с использованием1U
)?