C++中有没有一个计算单元的标准函数?

tma*_*ric 5 c++ floating-point

x对于二进制浮点数系统中的数字,最后一位的单位定义为ulp(x) = 2^{E(x)} * 2^{1 - p} = 2^{E(x)}*epsilon,其中指数是用于表示的以 2 为底的指数xp是数字格式的精度(53对于双精度格式),并且epsilon = 2^{1-p}是机器公差。

看着std::numeric_limits我期望找到类似的东西std::numeric_limits<double>::ulp(x),但这似乎不可用。或者类似的东西std::numeric_limits<double>::exponent(x)我可以乘以std::numeric_limits<double>::epsilon()但它不在那里。该功能似乎在boostulp中可用。

我可以自己编写一些代码,但我更愿意使用标准化代码(如果有的话)。我错过了文档中的某些内容吗?

编辑:为了更清楚地说明,我正在谈论浮点数的指数的计算,而不是浮点数格式(类型)x的获取min_max_指数范围。

eer*_*ika 1

标准库确实没有函数ulp

2^{E(x)}*ε

可以用下式计算:

int exp;
std::frexp(std::fabs(x), &exp);
double result = std::ldexp(std::numeric_limits<double>::epsilon(), exp - 1);
Run Code Online (Sandbox Code Playgroud)

警告:这仅适用于普通浮点值。对于非正规值,甚至可能不存在可以表示 ULP 的浮点值。


我希望找到类似的东西std::numeric_limits<double>::ulp(x),但这似乎不可用。或者类似的东西std::numeric_limits<double>::exponent(x)

numeric_limits仅包含常量(或返回常量的函数)。它没有任何执行计算的函数,因此没有接受输入值的函数。<cmath>标题具有计算功能。


作为一般读者的旁注:如果您的目的是找到下一个/上一个可表示的值,请使用nextafter函数系列而不是添加/减去 ULP。

  • 应使用“std::ldexp”而不是“std::pow”来操作浮点指数,因为它是为此目的而设计的,并避免了更复杂的幂函数固有的潜在舍入误差。 (3认同)
  • 对于次正规数,尝试通过将“std::frexp”获得的指数与“epsilon”相乘来计算 ULP 将失败,因为它们的 ULP 被限制在最低正常值的 ULP,而“std::frexp”继续报告它们的较低指数。 (3认同)
  • 对 ULP 使用 `std::pow(2, exp) * std::numeric_limits&lt;double&gt;::epsilon();` 会相差 2 的一个幂,因为 `std::frexp` 报告了一个按比例缩放的指数[½, 1) 中的有效数,而不是更常见的 [1, 2)。 (2认同)