Do-s и Don't-s для арифметики с плавающей запятой?

Каковы некоторые хорошие и не нужные для арифметики с плавающей запятой (IEEE754 в случае возникновения путаницы), чтобы обеспечить хорошую численную стабильность и высокую точность ваших результатов?

Я знаю, что некоторые из них, например, не вычитают количества одинаковой величины, но мне любопытно, какие другие хорошие правила существуют.

Ответы

Ответ 1

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

Вот некоторые правила/советы, которые я всегда соблюдал:

  • НИКОГДА не сравнивайте число с плавающей точкой с нулем или что-нибудь еще (IE не делает: if (myFloat == 0)
  • Ассоциативное свойство не выполняется для с плавающей запятой... значение (a + b) + c != a + (b + c)
  • Помните, что всегда есть закругление
  • Числа с плавающей запятой необязательно имеют уникальный обратный
  • Отсутствие замыкания с номерами с плавающей запятой... никогда не предполагайте, что результат операции с плавающей запятой приводит к действительному числу с плавающей запятой.
  • Распределительное свойство не содержит
  • Старайтесь избегать сравнения с плавающей запятой вообще... поскольку ошибка округления может привести к неожиданным результатам

Ответ 2

Правило №1 "не нужно" с числами с плавающей запятой:

Не использовать числа с плавающей запятой, где целые числа будут достаточными.

Ответ 3

DO понять, как ведет себя плавающая точка.

НЕ верьте, что простых правил будет достаточно, чтобы правильно их использовать.

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

Ответ 4

Запомните, что из-за ошибочной арифметики с плавающей запятой люди погибли и миллиард долларов убытки.

Ответ 5

никогда не пытайтесь сравнивать значение

double da, db;

...

if (da == db), то что-то.

помните, что C по умолчанию использует double, поэтому, если вы хотите сделать одинаковую точность, проясните это

float fa, fb;

...

fa = fb + 1.0;

преобразует fb, чтобы удвоить двойное добавление, затем преобразуется в одиночное и делает один равный

Вместо

fa = fb + 1.0F.

все одиночные.

Если вы собираетесь использовать целое число, например 1.0, не делайте его десятичным в коде. вы получаете больше надежности от своих компиляторов/инструментов, если можете свести к минимуму числа ascii. поэтому

fa = fb + 1;

или вместо

fa = fb + 0.3333333F;

сделайте что-нибудь подобное (если вы заинтересованы в точности).

fc = 1; fc = fc/3; fa = fb + fc;

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

Ответ 6

Моим "основным оружием" для избежания ловушек с плавающей запятой является твердое понимание того, как они работают. Я думаю, Chris Hecker очень хорошо объясняет основы.

Ответ 7

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