Как я могу определить частоту ошибок с плавающей запятой динамически? - PullRequest
3 голосов
/ 11 августа 2009

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

from the editor: please insert your code here. See HTML comment in the question source 

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

Ответы [ 4 ]

4 голосов
/ 11 августа 2009

См. мой ответ на Какое наименьшее ненулевое положительное число с плавающей точкой в ​​Perl? .

Этот код находит наименьшее положительное число, которое нельзя отличить от нуля. Вы можете адаптировать его к вашим потребностям.

3 голосов
/ 11 августа 2009

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

  • Это позволяет мне сосредоточиться на проблеме, которую я пытаюсь решить быстрее.
  • Мне не нужно тратить время на выяснение эпсилона!
  • также, и это важный момент: эпсилон меняется в зависимости от того, где вы находитесь в системе счисления. Эпсилон отличается около 0 и отличается около, скажем, 2 ^ 300. Таким образом, чтобы фактически подключить эпсилон, вам также необходимо знать, для какого диапазона чисел вы пытаетесь определить эпсилон. Я предлагаю использовать ответ Sinan Unur , но сделайте расчет около граничных значений диапазона чисел, с которым вы, вероятно, столкнетесь, а затем используйте эпсилон, который немного больше максимального значение.
  • проверьте пункт три, это просто догадка!
3 голосов
/ 11 августа 2009

Для 64-битного IEEE 754 с плавающей запятой наименьшее число, такое что 1.0 + e != 1.0 равно e = 2.2204460492503131e-016. (DBL_EPSILON в float.h в C, std::numeric_limits<double>().epsilon() в <limits> в C ++). Я думаю, что маловероятно, что ваш код будет работать на любых системах, где собственный формат с плавающей запятой не является 64-битным IEEE 754.

Обратите внимание, что абсолютная точность на самом деле меняется в зависимости от величины чисел, с которыми вы имеете дело. С денормалями вы оперируете чрезвычайно малыми значениями, поэтому 1e-300 + 2e-300 будет работать, но 1 + 1e-300 == 1. Аналогично 1e30 + 1 == 1e30.

1 голос
/ 11 августа 2009

«Точность станка», определяющая точность двойного или плавающего числа, обычно обозначается epsilon.

Если мне нужно вычислить точность числа с плавающей запятой, я обычно делаю что-то вроде этого *:

float number = 1.0;      // precision of this number
float epsilon = 1.0;

while ((number + epsilon) != number)
{
    epsilon /= 2.0f;
}

(* Это не в моей голове. Не используйте этот код без проверки.)

Но есть способы определения точной точности с учетом свойств машины.

Вот статья о Как определить машину epsilon с примерами кода.

И еще один здесь: С плавающей точкой: точность машины с теорией и уравнениями для расчета эпсилон.

Наслаждайтесь

Роберт К. Картейно

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