Умножение с плавающей точкой по сравнению с несколькими сложениями - PullRequest
1 голос
/ 10 февраля 2020

Хорошо, давайте предположим, что a - нормализованное число с плавающей запятой в базисе 2 (двоичная система). Правильно ли следующее равенство?

fl (a + a + a) = fl (3 * a)

Ответы [ 2 ]

2 голосов
/ 10 февраля 2020

Обозначения и предпосылки

a обозначает математическое число. a обозначает значение с плавающей точкой. 3 a обозначает математическое выражение (используя арифметику действительных чисел c). a+a+a и 3*a обозначают выражения, использующие арифметику с плавающей точкой c.

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

Конечные, нормальные значения

В двоичной переменной с плавающей точкой, если a является представимым и 2 a находится в пределах конечного диапазона, то 2 a представимо, так как единственная разница в их представлениях заключается в показателе степени. Поэтому, учитывая число с плавающей запятой a, представляющее число a , результат a+a в точности равен 2 a . Тогда результат с плавающей запятой a+a+a (который равен (a+a)+a) является математическим результатом 3 a (поскольку математический результат равен 2 a + a ) округлено до ближайшего представимого значения. И результат с плавающей точкой 3*a также является математическим результатом 3 a , округленным до ближайшего представимого значения. Поэтому a+a+a и 3*a имеют одинаковый результат с плавающей точкой, и равенство выполняется.

Особые случаи

Осталось рассмотреть особые случаи.

Если a, представляющее a , конечно, но 2 a превышает диапазон, для которого результат с плавающей запятой конечен, тогда a+a производит бесконечность, а a+a+a производит та же бесконечность, как и 3*a, поэтому равенство выполняется.

Если a - бесконечность, то a+a, a+a+a и 3*a производят ту же бесконечность, и выполняется равенство.

Если a является NaN, то a+a+a и 3*a являются NaN, и они не сравниваются равными, поскольку два NaN никогда не являются числами с одинаковыми значениями.

Сноска

1 Вопрос не определяет используемую систему с плавающей запятой. Конечно, можно определить систему с плавающей точкой, в которой 1+1 производит 0, а 0+1 производит 0, а 3*1 производит 5. Однако для целей этого ответа мы предполагаем типичную систему с плавающей запятой.

0 голосов
/ 10 февраля 2020

Вы не указали формат, IEEE 754 - популярный, но не единственный зверь.

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

Так что, как правило, не предполагайте, что это будет работать, но в этом конкретном случае c давайте начнем с формата IEEE в формате 1.fraction, нам не нужно очень много битов мантиссы, чтобы увидеть, как это работает.

1.ab c (a, b, c - единичные биты)

Как указывает Eri c, начать с 2 * a

  1abc
+ 1abc
========
 1xxx0

независимо от того, что c равно 1 или 0, lsbit равен 0. Фиксированная точка 1abc + 1ab c = 2 * 1ab c, пока мы не переполняем показатель степени:

  1abc
+ 1abc
========
 1abc0

вы можете пройтись по комбинациям и количеству битов мантиссы, если хотите.

добавление + a + a подходит к этой точке

 1abc0
+ 1abc
=======

для случая умножения

    1abc
    1100
  ====== 
    0000
   0000
  1abc
+1abc
===========

, который приходит к этой точке

   1abc
+ 1abc0
========

, поэтому они заканчиваются в том же месте, где они равны, да?

округление здесь не является фактором, так как результат младших битов в тех же значениях через любой путь ... да?

Отрицательные числа в IEEE, например, также используют положительный формат 1.f, а знак обрабатывается отдельно. В этом случае путь умножения p * p положителен, p * n отрицателен, поэтому оба пути работают, и вы сохраняете знак (здесь 3 всегда положительно). Для пути сложения результаты либо становятся более отрицательными, либо более положительными, они сохраняют свой знак.

Первое добавление может привести к переполнению показателя, что может привести к NAN, например, в IEEE. Второе дополнение, та же история. Умножение также может привести к созданию NAN, и лучше всего предположить, что по двум путям два результата NAN не являются бинарными, поэтому сравнение не будет работать. Если я правильно помню, один будет сигнализировать, а другой тихо, да?

Другие форматы. Все еще работать над этим должно быть так же легко продемонстрировать, как и в формате (форматах) 1.f. положительная 01. фракция, отрицательная 10.фракция, например.

Ключевым моментом здесь является то, что реализация умножения должна быть такой, чтобы она поддерживала 2 * n необходимого количества бит (для фиксированной точки n бит * n бит = 2 * n бит будет охватывать все случаи 32-битное число умножение на 32-битное число требует 64 бита для его хранения.) Форматы, стремящиеся к принудительной установке единицы в верхнюю часть значения, означают, что вы умножаете 1xxxxx ... * 1xxxxx .... из начальной школы

a.bcd
e.fgh
======

мы сделали бы математику как фиксированную точку abcd * efgh, а затем автоматически переместили бы десятичную точку 6 в результате. Затем двоичная плавающая точка должна будет нормализовать и переместить наиболее значимую 1 или 0 в зависимости от формата чуть левее двоичной точки, корректируя показатель степени, аналогично тому, как мы будем использовать степени 10 в нотации scientifi c для дальнейшего скорректировать результат. В идеале logi c будет использовать достаточно битов, чтобы математика с фиксированной точкой работала правильно, затем нормализовала это, затем обрезала и, возможно, округлила.

Так что в конце дня вы увидите что-то вроде

     abcd
    abcd
   abcd
  abcd
+ ...

И для случая 3 * a против a + a +

лучший случай, оставьте c в качестве залипшего бита

 1abc0
+ 1abc
=======
 xxxxx

худший случай обрезать его

 1abc0
+ 1abc
=======
 xxxx  

для умножения

лучший случай

    0000
   0000
  1abc
+1abc
===========
 xxxxxxx`

наихудшее ограничение

    0 
   00 
  1ab 
+1abc
===========
 xxxx`

в обоих случаях мы сохраняем / теряем один бит, который будет идти вниз по обоим путям, даст одинаковый результат, если и сложение, и умножение сделают одинаковые оптимизации. Это только тот случай, когда 3 * a против a + a + a, придется пройти через возможности для любого другого уравнения.

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

Предположим, что в одном случае вы будете счастливы, если это не так, даже лучше, если вы сможете доказать, что это не так (для вашего конкретного c целевого оборудования или формата в целом), а затем запомнить и задокументировать ограничения этого доказательства. Если вы забудете доказательство или не документируете правила, тогда кто-то придет позже и испортит, и математика может / будет неправильной, и программное обеспечение не будет работать. Поэтому будьте очень, очень осторожны, делая математические оптимизации, не продумывая их В частности, если вы ожидаете равного сравнения для работы.

Я работал над системами управления, где мы должны были изменить lsbit мантиссы, чтобы математика работала, вычисление входной двери констант не давало правильного набора значений. Любая дальнейшая корректировка параметров этих систем управления потребует проверки значений и, возможно, настройки одного или нескольких из них, чтобы математика работала.

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