Назначение 2 ^ 31 для поплавка или двойного

Я должен умножить целочисленное значение на 2 ^ 31. Я гуглил это, и похоже, что у двойников есть диапазон между 2.23e-308 <= | X | <= 1.79e308 при использовании 64 бит и число с плавающей запятой среди 1.18e-38 <= | X | <= 3.40e38.

Это намного больше, чем мне нужно. Но это не работает.

У меня есть это постоянное значение в моем заголовочном файле:

static const float SCALE_FACTOR = 2^-31;

и если тогда я просто делаю:

float dummy = SCALE_FACTOR;

Тогда значение макета равно 11.

Я не знаю, если проблема заключается в том, чтобы присвоить постоянное значение, как это, но я не знаю, как еще написать это без потери точности.

Любая помощь?

РЕДАКТИРОВАТЬ: Извините, глупый вопрос. Мой опыт в MatLab предал меня и забыл, что ^ не для возведения в степень в C ++. Я проголосовал за закрытие.

-3

Решение

^ — побитовый оператор xor в C ++, а не математический оператор возведения в степень. У вас есть несколько альтернатив.

  1. Поскольку вы храните константу в формате с потерями, floatМожно просто отработать базу-10 e Форма буквально и использовать это: возможно, что-то вроде 4.6566128730773926e-010 за 2 ^ -31. Это подвержено ошибкам (например, я их сделал) и не обязательно переносимо между форматами с плавающей запятой.
  2. Вы можете установить константу, используя константное выражение, которое можно оценить во время компиляции, и использовать целочисленный литерал: либо 0x80000000 или же 1UL << 31 за 2 ^ 31 или 1.0f / 0x80000000 для 2 ^ -31 например.

Вы могли бы использовать pow Конечно, функция для вычисления значения во время выполнения.

Кстати, если вы используете целые числа, почему бы просто не использовать long long или другой 64-битный целочисленный тип вместо плавающей запятой, который вполне может представить вам ошибки округления? Из вашего вопроса не совсем понятно, смотрите ли вы на значения с плавающей запятой, потому что вы необходимость диапазоны значений с плавающей запятой или потому, что вы просто беспокоитесь о переполнении 32-битного целочисленного значения.

3

Другие решения

В вашем коде

static const float SCALE_FACTOR = 2^-31;

static избыточно (константы имеют внутреннюю связь по умолчанию), ^ обозначает побитовое XOR, - бессмысленно (по крайней мере, если вы хотите «умножить на 2 ^ 31», как указано), и float без необходимости особый выбор, в отличие от типа с плавающей точкой по умолчанию double (например, это тип литерала с плавающей запятой, такой как 3.14).

Также в C ++ резервный крик ВСЕХ UPPERCASE-идентификаторов для макросов (общее соглашение). Использование их для констант — это Java-изм. По иронии судьбы соглашение Java возникло в C, где в прошлом константы должны были выражаться как макросы.

Вместо этого пишите

double const scale_factor = 1uL << 31;

где

  • не указывать явно внутреннюю связь (ключевое слово static),

  • используя тип с плавающей точкой по умолчанию double вместо float,

  • не использовать ALL UPPERCASE идентификатор (который должен быть зарезервирован для макросов),

  • используя левое смещение << вычислить степень двух вместо неправильных ^,

  • не добавляя ни одного бессмысленного знака минус,

  • используя тип unsigned long (указано uL) чтобы быть уверенным, чтобы иметь достаточный диапазон.

1

^ является оператором для побитового XOR, а не для возведения в степень. Тебе нужно std::pow(),

0

Умножение на степень 2 эквивалентно сдвигу влево на эту степень. Чтобы умножить целое число на два до 31, просто сдвиньте его:

unsigned long value = whatever;
unsigned long value_times_2_to_the_31 = value << 31;

Там нет необходимости для математики с плавающей точкой здесь. Но для полноты, чтобы получить двойное значение от 2 до 31:

double two_to_the_31 = std::ldexp(1.0, 31);

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

0
По вопросам рекламы [email protected]