C++ 将字符串(strtold)转换为长双精度,然后从长双精度中减去,得到>;ε

C++ 将字符串(strtold)转换为长双精度,然后从长双精度中减去,得到>;ε,c++,C++,不确定是否有人遇到过这种情况,并能帮助找到解决方案 基本上,我把一个字符串转换成一个浮点值,然后从一个浮点值中减去,看看差值是否在+/-ε范围内 问题是我做错了什么,在长双打中得到了不同的结果 看起来两个长双精度之间的差异产生了一个与浮点精度相同的值,但不确定为什么 代码的输出(mac和linux 64位都给出了相同的结果) 这是密码 #include <limits> #include <cstddef> #include <iostream> #inclu

不确定是否有人遇到过这种情况,并能帮助找到解决方案

基本上,我把一个字符串转换成一个浮点值,然后从一个浮点值中减去,看看差值是否在+/-ε范围内

问题是我做错了什么,在长双打中得到了不同的结果

看起来两个长双精度之间的差异产生了一个与浮点精度相同的值,但不确定为什么

代码的输出(mac和linux 64位都给出了相同的结果)

这是密码

#include <limits>
#include <cstddef>
#include <iostream>
#include <sstream>
#include <cmath>

template <typename T>
bool cmp_equal(const T& lhs,
               const T& rhs,
               const T& epsilon = std::numeric_limits<T>::epsilon()) {
    const T diff = (lhs - rhs);
    return ((diff >= -epsilon) && (diff <= epsilon));
}

int main()
{
    float a = 145.5678f;
    double b = 145.5678;
    long double c = 145.5678l;

    std::stringstream s("145.5678 \r\t\n");
    char* end;

    float d = std::strtof(s.str().c_str(), &end);
    double e = std::strtod(s.str().c_str(), &end);
    long double f = std::strtold(s.str().c_str(), &end);

    std::cout << "float        : " << "a=" << a << " d=" << d
              << " epsilon=" << std::numeric_limits<float>::epsilon()
              << " fabsf(a - d)=" << std::fabsf(a - d)
              << " equal? " << (cmp_equal(a, d)?"equal":"not equal")
              << std::endl;

    std::cout << "double       : " << "b=" << b << " e=" << e
              << " epsilon=" << std::numeric_limits<double>::epsilon()
              << " fabs(b - e)=" << std::fabs(b - e)
              << " equal? " << (cmp_equal(b, e)?"equal":"not equal")
              << std::endl;

    std::cout << "long double  : " << "c=" << c << " f=" << f
              << " epsilon=" << std::numeric_limits<long double>::epsilon()
              << " fabsl(c - f)=" << std::fabsl(c - f)
              << " equal? " << (cmp_equal(c, f)?"equal":"not equal")
              << std::endl;
}
#包括
#包括
#包括
#包括
#包括
模板
布尔cmp_相等(常数T和lhs,
康斯特T&rhs,
常数T&epsilon=std::numeric_limits::epsilon()){
常数T差异=(lhs-rhs);

return((diff>=-epsilon)&&(diff正如您所提到的,看起来长双精度差等于浮点精度(尽管它是双精度)

与文字整数一样,文字浮点也可以被转换,因此转换使用特定类型。默认情况下,该类型为双精度

要获得所需的精度,您必须做到以下几点:

float a = 145.5678f;
double b = 145.5678;
long double c = 145.5678l;

的'f'(或'f')浮动
长双精度的'l'(或'l')

注意使用
fabs()
表示您不知道哪个数字更大。请注意,您的输出显示的数字集与代码中的数字集不同。请记住,ε是可以添加到1中以产生不同值的最小值。当您查看145.5678这样的数字时,它太小而无法显示。感谢您的快速响应onse…Alex:cout精度可能会对显示的值进行四舍五入…但不应影响计算;对吗?…也使用晶圆来显示差异…但我的cmp equal不使用晶圆…谢谢Pete…所以从你的评论中我得到的基本上是不要对小值使用长双精度?…如果我使用比双精度大的数字然后做差异…。它会起作用…@goffer你能投票给这个答案并接受它吗?(向上箭头并在答案左边打勾)
float a = 145.5678f;
double b = 145.5678;
long double c = 145.5678l;