Печать наибольшего числа для типов в c — борьба с правильными типами форматирования

#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 )?