我可以编写const表达式double,它是两个小于-0.5的ulps

Joh*_*don 5 c++ floating-point floating-accuracy

我根据通过json数据包收到的数字进行了一组浮点计算.在我的计算结束时,我要求其中一个数字> = -0.5.我发现有时我的测试值不合格,因为它是一个低于阈值的ULP.无论如何要写一个意味着类似的东西

constexpr auto threshold = -0.5 - 2*ULP;
Run Code Online (Sandbox Code Playgroud)

或者我必须采取类似的方式

auto threshold = -0.5;
threshold = std::nexttoward(threshold, -2.0);
threshold = std::nexttoward(threshold, -2.0);
Run Code Online (Sandbox Code Playgroud)

gez*_*eza 3

也许类似这样的东西可以做到这一点(它需要基数2浮点表示,并且不适用于非正规数):

constexpr double num = -0.5;
constexpr double threshold = num + 
          2.0 
        * (num < 0 ? -1 : 1) 
        * std::pow(2.0,
                   std::floor(std::log(std::abs(num)) / std::log(2.0))) 
        * std::numeric_limits<double>::epsilon();
Run Code Online (Sandbox Code Playgroud)

它是如何工作的(我以 IEEE754 来描述它)?

当数字在 [1.0;2.0) 范围内时,Epsilon 表示 1 ULP。我们需要缩放 epsilon,因此它始终意味着 1 ULP。标度基于浮点数的指数部分。如果数字为 [1.0;2.0),则小数位数必须为 1。如果数字为 [2.0;4.0),则小数位数必须为 2,对于 [4.0;8.0),则小数位数必须为 4,依此类推,我们需要找到最接近的、小于或等于 2 的幂:它是2^floor(log2(number))。我们需要处理负数,这就是公式中的abs和 的原因。(num<0?-1:1)