Целочисленная константа слишком велика для своего типа и недопустимых операндов для бинарных операторов - PullRequest
1 голос
/ 13 февраля 2012

Я использую double long в моем 64-битном компьютере, а sizeof(double long) - 16 bytes.Поэтому я выполняю следующее задание:

  long double f = 0xA0000000000000000000000000000000; // 32 characters in hex

и получаю это предупреждение: warning: integer constant is too large for its type.Это предупреждение не кажется правильным, моя константа может быть легко сохранена в 128-битном значении.Итак, почему я получаю предупреждение?

У меня также есть этот код:

  long double tmp = 0x90000000CCCCCCCC0000000000000000;
  long double res = (f & tmp);  // where f is the previously defined variable

, и я получаю следующую ошибку error: invalid operands to binary &.Почему?

Ответы [ 3 ]

2 голосов
/ 13 февраля 2012
error: invalid operands to binary &

, потому что f и tmp являются числами с плавающей запятой, а не целыми числами, они не могут служить аргументом для двоичного файла &.

long double f = 0xA0000000000000000000000000000000

Вы инициализируете переменную с плавающей точкой целочисленной константой.Это само по себе нормально, но целочисленная константа имеет свой собственный тип, который может быть таким же большим, как и самый большой целочисленный тип (компилятор выбирает подходящий тип).Если у самого большого целочисленного типа в вашем компиляторе меньше 128 бит, это не сработает.

Кстати, sizeof(double long) == 16 не означает, что long double имеет 128-битное представление.

1 голос
/ 13 февраля 2012

0xA0000000000000000000000000000000 является целочисленной константой и в зависимости от вашей системы может не поддерживаться.Большой тип целочисленной константы - unsigned long long, и если ширина unsigned long long в вашей системе равна 64-битной, эта константа не подойдет.

Что вы можете сделать, это использовать шестнадцатеричный* плавающая константа вместо шестнадцатеричной целочисленной константы.

long double f = 0xA0000000000000000000000000000000p0L;
                                                  ^^ the exponent is 0

в порядке.

p представляет показатель степени (обязательно), а L указывает, что это long double литерал (по умолчанию double).

Шестнадцатеричная плавающая константа является дополнением к C99 и обратите внимание, что в шестнадцатеричных плавающих константах требуется экспонента.

Относительно побитовых операторов (вторая частьвашего вопроса), операнды побитовых операторов должны быть целочисленных типов, поэтому вы не можете выполнять побитовые операции над значениями с плавающей запятой.

1 голос
/ 13 февраля 2012

Расширение моего комментария:

long double - это тип с плавающей точкой.Вот почему вы не можете использовать для них побитовые операторы.

К сожалению, стандарт не гарантирует 128-битный целочисленный тип.Единственный известный мне компилятор, который на самом деле поддерживает его как расширение - GCC через __int128 .(РЕДАКТИРОВАТЬ: он не выглядит, он всегда поддерживает его.)

MSVC также имеет тип __int128, но он остается только зарезервированным и не реализованным.

Если вы только делаете бит-процедурные операции, вы можете использовать структуру с двумя 64-битными целыми числами.Или, если вы используете x86, вы можете использовать 128-битные типы данных SSE.

...