【问题标题】:converting string (strtold) to long double and subtracting from long double gives > epsilon将字符串 (strtold) 转换为 long double 并从 long double 中减去 > epsilon
【发布时间】:2016-03-26 19:54:13
【问题描述】:

不确定是否有人遇到过这个问题并可以帮助找到解决方案。

基本上我将字符串转换为浮点值,然后从浮点值中减去以查看差异是否在 +/- epsilon 内

问题是我做错了什么才能得到不同的结果?

看起来 2 个 long double 之间的差异产生的值与 float 的精度相同,但不知道为什么......

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

float        : a=145.568 d=145.568 epsilon=1.19209e-07 fabsf(a - d)=0 equal? equal
double       : b=145.568 e=145.568 epsilon=2.22045e-16 fabs(b - e)=0 equal? equal
long double  : c=145.568 f=145.568 epsilon=1.0842e-19 fabsl(c - f)=5.41234e-15 equal? not equal

这里是代码

#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;
}

【问题讨论】:

  • 请注意,使用fabs() 意味着您不知道哪个数字更大。
  • 请注意,您的输出显示的数字集与代码中的数字不同。
  • 请记住,epsilon 是可以加到 1 以产生不同值的最小值。当您查看像 145.5678 这样的数字时,它太小而无法显示。
  • 感谢您的快速响应... Alex:cout 精度可能会四舍五入显示的内容.. 但不应影响计算;对吗?.... 也使用 fabs 来显示差异...但是我的 cmp equal 不使用 fabs...
  • 谢谢皮特......所以我从你的评论中得到的基本上是不要将 long double 用于小值?......也就是说,如果我使用大于 double 的数字并做差异.. ..它会工作....

标签: c++


【解决方案1】:

正如您所提到的,long double 差值似乎等于 float 精度(虽然它是双精度)。

文字浮点数,如文字整数,可以是followed by a suffix,因此转换使用特定类型。默认情况下,类型为 double。

要获得所需的精度,您应该具备以下条件:

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

floats 的“f”(或“F”)和long double 的“l”(或“L”)。

【讨论】:

  • @goffer 你能支持这个答案并接受它吗? (答案左侧的向上箭头和打勾)
猜你喜欢
  • 1970-01-01
  • 2014-09-30
  • 2019-05-20
  • 2015-08-23
  • 2021-12-03
  • 2013-01-20
  • 1970-01-01
  • 1970-01-01
  • 2014-02-02
相关资源
最近更新 更多