Boost muliprecision cpp_dec_float仅与所需精度进行比较

时间:2014-12-09 12:19:07

标签: boost floating-point compare decimal multiprecision

我正在使用boost :: multiprecision库来处理十进制浮点类型,并希望将两个浮点数与指定的精度进行比较。

但是,cpp_dec_float似乎将数字与指定的精度进行比较,但也包括保护数字:

#include <iostream>

#include <boost/multiprecision/cpp_dec_float.hpp>
//#include <boost/math/special_functions.hpp>

typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50> > flp_type;

int main(int argc, char* argv[])
{
    // 50 decimal digits
    flp_type sqrt2("1.4142135623730950488016887242096980785696718753769");
    // Contains calculated guard digits
    flp_type result(boost::multiprecision::sqrt(flp_type("2")));

    // The 50 digits of precision actually ompare equal
    std::cout << std::setprecision(50) << sqrt2 << std::endl;
    std::cout << std::setprecision(50) << result << std::endl;
    // I want this to compare to the specified precision of the type, not the guard digits
    std::cout << (result==sqrt2) << std::endl;

    return 0;
}

输出:

1.4142135623730950488016887242096980785696718753769
1.4142135623730950488016887242096980785696718753769
0

预期:

1.4142135623730950488016887242096980785696718753769
1.4142135623730950488016887242096980785696718753769
1

See on Coliru

我试图用precision()来“截断”,但无济于事。 有没有办法比较这两个数字而不采用epsilon比较?

2 个答案:

答案 0 :(得分:2)

如果剥去防护位,则会有效地削弱该类型的保真度。

一种可靠的方法是使用(反)序列化,真的。

所以我建议

<强> Live On Coliru

// Either
std::cout << std::numeric_limits<flp_type>::epsilon() << "\n";
std::cout << (abs(result-sqrt2) < std::numeric_limits<flp_type>::epsilon()) << std::endl;

// Or
result = flp_type { result.str(49, std::ios::fixed) };
std::cout << (result==sqrt2) << std::endl;

请注意,epsilon是1e-49那里

打印

1.4142135623730950488016887242096980785696718753769
1.4142135623730950488016887242096980785696718753769
1e-49
1
1

显然,基于epsilon()的比较会显得效率更高

答案 1 :(得分:0)

bool is_equal = abs(result-sqrt2) < std::pow(10, -std::numeric_limits< flp_type >::digits10 );