Побитовое представление деления поплавков - как работает деление поплавков - PullRequest
2 голосов
/ 30 марта 2012

Число может иметь несколько представлений, если мы используем число с плавающей запятой, поэтому результаты деления числа с плавающей запятой могут давать поразрядные числа с плавающей запятой.Но что, если знаменатель имеет степень 2?

AFAIK, деление на степень 2 только сместит экспоненту, оставив одну и ту же мантиссу, всегда производящую поразрядно идентичные числа с плавающей точкой.Это верно?

float a = xxx;
float result = n/1024f; // always the same result?

--- ОБНОВЛЕНИЕ ----------------------

Извините за отсутствиезнание черной магии IEEE для чисел с плавающей запятой :), но я говорю о тех числах, о которых упоминал Гуванте: нет представления для определенных десятичных чисел, «неточные» числа с плавающей запятой.В оставшейся части этого поста я буду использовать «точные» и «неточные», учитывая определение этих слов Гуванте.

Для упрощения, скажем, числитель всегда является «точным» числом.Кроме того, давайте разделим не на любую степень 2, а всегда на 1024. Кроме того, я выполняю операцию каждый раз одинаково (один и тот же метод), поэтому я говорю о получении одинаковых результатов в разных исполнениях (дляточно такие же входытолько сдвиньте экспоненту, все еще имея «точное» значение с плавающей точкой.

Вы попросили привести пример.Реальная проблема заключается в следующем: у меня есть симулятор, выдающий иногда 0.02999994, а иногда 0.03000000 для одних и тех же входов.Я думал, что мог бы умножить эти числа на 1024, округлить, чтобы получить «целое» («точное» число с плавающей точкой), которое было бы одинаковым для этих двух чисел, а затем разделить на 1024, чтобы получить «точное» округленное число с плавающей точкой.

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

Ответы [ 2 ]

5 голосов
/ 30 марта 2012

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

Вопрос, как представляется, основан на неверной предпосылке;единственное число, которое имеет несколько представлений в виде числа с плавающей точкой, это ноль, который может быть представлен как «положительный ноль» или «отрицательный ноль».Помимо нуля, данное число имеет только одно представление в виде числа с плавающей точкой, если предположить, что вы говорите о типах типа «double» или «float».Является ли проблема, о которой вы говорите, тот факт, что компилятору разрешено выполнять операции с плавающей запятой с более высокой точностью, чем 32 или 64-битные доступные для хранения ?Это может привести к тому, что в некоторых случаях деления и умножения приводят к разным результатам.

4 голосов
/ 30 марта 2012

Поскольку люди часто не в полной мере понимают числа с плавающей запятой, я очень быстро рассмотрю некоторые из них.Каждая конкретная комбинация битов в числе с плавающей запятой представляет уникальный номер.Однако, поскольку это число имеет дробный компонент с основанием 2, для некоторых десятичных чисел нет представления.Например, 1.1.В этих случаях вы берете ближайший номер. IEEE 754-2008 указывает округление до ближайшего, связывается даже с этими случаями.

Реальная сложность заключается в том, что вы комбинируете два из этих «неточных» чисел.Это может вызвать проблемы, поскольку каждый промежуточный этап будет включать округление.Если вы рассчитываете одно и то же значение двумя разными методами, вы можете придумать несколько разные значения.Как правило, это решается эпсилоном, когда вы хотите равенства.

Теперь перейдем к вашему реальному вопросу: можете ли вы разделить на две степени и избежать дополнительных «неточностей»?Обычно вы можете, однако, как и для всех чисел с плавающей запятой, денормалы и другие нечетные случаи имеют свою собственную логику, и, очевидно, если ваша мантисса переполнится, у вас возникнут трудности.И еще раз отметим, что во время всего этого не возникает никаких математических ошибок, это просто математика, выполняемая с ограниченной точностью, что включает в себя периодическое округление результатов.

РЕДАКТИРОВАТЬ: В ответ на новый вопрос

То, что вы говорите, может сработать, но в значительной степени эквивалентно округлению.Кроме того, если вы просто ищете равенство, вы должны использовать эпизод, как я упоминал ранее (a - b) < e, для небольшого значения e (0.0001 будет работать в вашем примере).Если вы хотите распечатать симпатичное число, а используемая вами среда не подходит вам по вкусу, некоторое округление будет самым прямым способом описания вашего решения, что всегда является плюсом.

...