gpt4 book ai didi

c++ - 如何检查两个数字是否在浮点类型精度限制的 "x"有效数字范围内?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:50:04 27 4
gpt4 key购买 nike

假设我们有一个浮点类型的 XType,其中有两个数字:

XType const a = 1.2345
XType const b = 1.2300

然后我想要一个函数 IsClose(XType const f1,XType const f2,unsigned const truncated_figures) 这样

// the numbers are equal if the last two figures are ignored (1.23 == 1.23)
IsClose<XType>(a,b,2) == true

// the numbers are not equal if only the last is ignored (1.234 != 1.230)
IsClose<XType>(a,b,1) == false

到目前为止,我遇到了这个丑陋的烂摊子,但我还没有说服自己这是正确的:

// check if two floating point numbers are close to within "figures_tolerance" figures of precision for the applicable type
template <typename FloatType>
bool const IsClose(FloatType const f1, FloatType const f2, unsigned const figures_tolerance)
{
FloatType const tolerance_exponent = std::pow(10.0,figures_tolerance);
FloatType const tolerance =
std::pow(tolerance_exponent,std::log10(f1)) *
std::numeric_limits<FloatType>::epsilon()
;
return std::abs(f1 - f2) < tolerance;
}

我的理由是公差应该是提高到数量超过或子种子 1.0(epsilon 所基于的有效数字)的数量级的 epsilon。这有意义吗?有没有更好、更可靠的方法?

编辑:我使用模板函数的解决方案如下(它基于下面 user763305 的回答)

// check if two floating point numbers are within the last n digits of precision for the
// largest of the two numbers being compared.
template <typename FloatType>
bool const IsWithinPrecision(FloatType const f1, FloatType const f2, unsigned const n = 1U)
{
FloatType const f_ref = std::max(std::abs(f1), std::abs(f2));
FloatType const distance = std::abs(f1 - f2);
FloatType const e = std::numeric_limits<FloatType>::epsilon();

return distance < std::pow((FloatType) 10.0, (FloatType) n) * e * f_ref;
}

最佳答案

要测试两个数字是否在彼此的 n 有效数字范围内,请使用不等式

abs(a - b) < pow(0.1, n) * max(abs(a), abs(b))

但是,我通常发现测试有效数字的数量是否至少是有效数字的最大可能数量(给定浮点类型的精度)减去 n 更有用。这可以使用不等式来完成

abs(a - b) < pow(10.0, n) * std::numeric_limits<...>::epsilon() * max(abs(a), abs(b))

换句话说,n 是我们因舍入误差丢失 的有效位数。像 n = 23 这样的东西通常在实践中有效。

之所以可行,是因为 float aa 下方和上方的下一个可表示 float 之间的距离位于

0.5 * std::numeric_limits<...>::epsilon() * abs(a)

std::numeric_limits<...>::epsilon() * abs(a)

此外,如果您处理的是非常小的数,或者更准确地说,是非正规数,则上述不等式将不起作用。那么你应该改用不等式

abs(a - b) < pow(10.0, n) * max(
std::numeric_limits<...>::epsilon() * max(abs(a), abs(b)),
std::numeric_limits<...>::denorm_min()
)

关于c++ - 如何检查两个数字是否在浮点类型精度限制的 "x"有效数字范围内?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17380970/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com