Как (портативно) получить DBL_EPSILON в C и C++

Ваш пример будет связан во время компиляции. Все встроенные строки и строковые переменные константы связываются во время компиляции.

Что-то для учета - то, который включая любые строки только для чтения задержит concatting ко времени выполнения. строка. Пустой и Среда. NewLine являются оба строковыми переменными только для чтения.

13
задан Ken Y-N 20 September 2019 в 00:29
поделиться

2 ответа

Он должен быть в "float.h". Это переносимо, это часть стандартов C и C ++ (хотя и не рекомендуется в C ++ - используйте или ответ 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

Edit: Я не совсем понимаю, что вы имеете в виду под «программно». Это стандартная константа, вы не должны ее вычислять, это свойство реализации, данное вам в файле заголовка. Но я думаю, вы могли бы сделать что-то подобное. Опять же, предполагая представление 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 . Грубо говоря, на ПК это зависит от того, использует ли ваш компилятор инструкции FPU x86 (более высокая точность) или более новые операции x64 с плавающей запятой (двойная точность).

28
ответ дан 1 December 2019 в 17:24
поделиться

В C ++ это std :: numeric_limits :: epsilon ( ) .

31
ответ дан 1 December 2019 в 17:24
поделиться