Я пытаюсь реализовать Matlab’s eps(x)
функция в C ++
Например, в Matlab:
>> eps(587.3888)
ans = 1.1369e-13
>> eps(single(587.3888))
ans = 6.1035e-05
Однако, когда я пытаюсь сделать это в C ++, я не могу получить правильный ответ с одинарной точностью.
#include <limits>
#include <iostream>
#include <math.h>
#define DEBUG(x) do { std::cerr << x << std::endl; } while (0)
#define DEBUG2(x) do { std::cerr << #x << ": " << x << std::endl; } while (0)
int main() {
float epsf = std::numeric_limits<float>::epsilon();
DEBUG2(epsf);
double epsd = std::numeric_limits<double>::epsilon();
DEBUG2(epsd);
float espxf = nextafter(float(587.3888), epsf) - float(587.3888);
double espxd = nextafter(double(587.3888), epsd) - double(587.3888);
DEBUG2(espxf);
DEBUG2(espxd);
}
Запустив программу, я получаю следующий вывод:
$ ./a.out
epsf: 1.19209e-07
epsd: 2.22045e-16
espxf: -1.13687e-13
espxd: -1.13687e-13
По какой-то причине кажется, что хотя значения eps для одинарной и двойной точности верны, вывод с использованием nextafter
Функция выводит только значение двойной точности. Моя ценность для epsxf
должно быть 6.1035e-05, как в Matlab.
Какие-нибудь мысли?
Включают <cmath>
и позвонить std::nextafter
и ваш код будет работать при условии, что у вас есть компилятор C ++ 11.
В том числе <math.h>
и звонит ::nextafter
вызывает C-версию функции. C реализация nextafter
очевидно, не поддерживает никаких перегрузок, поэтому C обеспечивает nextafterf
для получения результата с одинарной точностью, а также nextafterl
для четверной точности. (Просто вызов двойной точности nextafter
с float
не удается, потому что аргумент преобразуется в double
.) Если у вас нет компилятора C ++ 11, вы можете исправить свой код, вызвав ::nextafterf
,
Используйте библиотеки. Matlab-х eps
Функция на других языках называется ULP, за единицу на последнем месте. Согласно статье в Википедии ULP, следующая функция из повысить C ++ библиотека может использоваться для вычисления расстояния с плавающей точкой между двумя двойными a
а также b
:
boost::math::float_distance(a, b)
Документация для float_distance
является Вот.