десятичный литерал больше чем LONG_LONG_MAX - PullRequest
0 голосов
/ 27 мая 2018

В книге "C ++ Primer" говорится, что десятичные литералы имеют наименьший тип int, long или long long, которому соответствует значение литерала, и использование литерала, который являетсяслишком большой, чтобы поместиться в самый большой связанный тип.Итак, я предполагаю, что максимальный десятичный литерал - это максимальное значение, которое может содержать long long.Но я попробовал: напечатал значение max long long, затем десятичный литерал выше.Я думал, что это должно было вызвать ошибку, но это было хорошо.Затем я попытался напечатать десятичный литерал выше значения unsigned long long max - оно обернулось вокруг.

Вот мой код:

#include <iostream>
#include <limits>

using namespace std;

int main() {
    cout << LONG_LONG_MAX << endl;
    cout << 9223372036854775808 << endl;
    cout << ULONG_LONG_MAX << endl;
    cout << 18446744073709551616 << endl;
}

Вот результат:

9223372036854775807
9223372036854775808
18446744073709551615
0

Объясните, пожалуйста, почему десятичный литерал может быть выше, чем long long максимальное значение

UPD :

Я заметил, что на самом деле были предупреждения.Я работаю в CodeBlocks, и при перестройке и повторном запуске вашего проекта он не выводит предупреждения снова, если код не изменен.Так что я просто не заметил.Было 3 предупреждения:

integer constant is so large that it is unsigned (8)
this decimal constant is unsigned only in ISO C90 (8)
integer constant is too large for its type (10)

Но вывод был тот же.Затем я заметил, что в опциях отладчика я забыл заполнить строку 'путь к исполняемому файлу', поэтому вставил туда свой путь к GDB.Но я не думаю, что это имело значение.Впоследствии я заметил, что в настройках компилятора я не выбрал опцию «иметь g ++ follow c ++ 11».Я выбрал компилятор, а затем напечатал как предупреждения, так и некоторые ошибки.Не было предупреждения this decimal constant is unsigned only in ISO C90, но была ошибка ..\main.cpp|8|error: ambiguous overload for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and '<unnamed-signed:128>')|.Также он не распознал limits с LONG_LONG_MAX и ULONG_LONG_MAX, но распознал climits с LLONG_MAX и ULLONG_MAX.С c ++ 98 были предупреждения, как в первом случае (без выбранной опции), и он не распознавал limits, только climits.Когда я изменил имя заголовка, вывод был как в начале.Компилятор настроен на GNU GCC Compiler.

Может быть, кто-то может объяснить, почему компилятор поддерживает limits, если я не задаю стандарт, и тогда, я думаю, вопрос закрыт.

Ответы [ 2 ]

0 голосов
/ 27 мая 2018

Пожалуйста, используйте заголовок и константы, определенные стандартом.http://en.cppreference.com/w/cpp/types/climits.

Верхний предел для 64-битного int (long long в большинстве систем POSIX) составляет 9223372036854775807 (2 ^ 63-1).Максимальное значение для объекта типа unsigned long long int 18446744073709551615 (2 ^ 64-1).

<limits> может существовать, но не обязательно, включает <climits>.

Поскольку ваш литерал нене вписывается в значение со знаком, компилятор должен предоставить вам диагностику (если вы ее не отключили), что-то вроде

main.c:8:13: warning: integer constant is so large that it is unsigned
    cout << 9223372036854775808 << endl;

Очевидно, что gcc \ clang достаточно либерален, чтобы считать это достаточным, и может компилироватьпрограмма, предполагающая, что значение будет представлено беззнаковым типом, и усечение второго литерала.Это неопределенное поведение и прежнее не будет истинным, поэтому вы можете получить отрицательные значения в выводе, например:

9223372036854775807
-9223372036854775808
18446744073709551615
0 
0 голосов
/ 27 мая 2018

В соответствии со спецификацией языка, десятичный литерал без суффикса имеет тип со знаком (наименьший тип int, long int или long long int, который может содержать значение).Двоичные, восьмеричные и шестнадцатеричные константы могут иметь типы без знака.

Реализация может поддерживать расширенные целочисленные типы .Если ваш компилятор имеет целочисленный тип, больший чем long long, тогда ваш десятичный литерал будет иметь этот тип.Если это не так, то это либо ошибка компилятора, либо расширение компилятора, поскольку нефиксированный десятичный литерал не может быть типа unsigned long long.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...