Я использую GCC 3.4 для Linux (AS 3) и пытаюсь найти, чтобы получить DBL_EPSILON
или, по крайней мере, приличное приближение. Как я могу получить это программно?
Как (переносимо) получить DBL_EPSILON в C и С++
Ответ 1
Он должен быть в "float.h". Это переносимо, это часть стандартов C и С++ (хотя и устарела на С++ - используйте <cfloat>
или sbi ответ для "гарантированной" передовой совместимости).
Если у вас его нет, то, поскольку ваши парные разряды являются 64-битными IEEE, вы можете просто украсть это значение у кого-то другого float.h. Вот первый, который я нашел:
http://opensource.apple.com/source/gcc/gcc-937.2/float.h
#define DBL_EPSILON 2.2204460492503131e-16
Значение выглядит правильно для меня, но если вы хотите быть уверенным в своем компиляторе, вы можете проверить, что (1.0 + DBL_EPSILON) != 1.0 && (1.0 + DBL_EPSILON/2) == 1.0
Изменить: я не совсем уверен, что вы подразумеваете под "программным способом". Это стандартная константа, вы не должны ее вычислять, это свойство реализации, данное вам в файле заголовка. Но я думаю, вы могли бы сделать что-то подобное. Опять же, если предположить, что представление IEEE или что-то в этом роде, так что DBL_EPSILON должен быть любой мощностью 0,5, представляет собой 1 в последнем бите точности представления 1.0:
double getDblEpsilon(void) {
double d = 1;
while (1.0 + d/2 != 1.0) {
d = d/2;
}
return d;
}
Остерегайтесь того, что в зависимости от настроек компилятора промежуточные результаты могут иметь более высокую точность, чем double
, и в этом случае вы получите меньший результат для d
, чем DBL_EPSILON
. Проверьте свое руководство по компиляции или найдите способ, чтобы значение 1.0 + d/2
было сохранено и перезагружено до фактического объекта double
, прежде чем сравнивать его с 1.0
. Очень грубо говоря, на ПК это зависит от того, использует ли ваш компилятор инструкции x86 FPU (более высокая точность) или новые операторы с плавающей запятой x64 (двойная точность).
Ответ 2
В С++ он std::numeric_limits<double>::epsilon()
.