将一个双倍圆到最近且更大的浮点数

use*_*030 5 c c++ floating-point rounding

我想使用c/c ++将大的双数(> 1e6)舍入到最接近但更大的浮点数.我尝试了这个,但我不确定它是否总是正确的,并且可能有一种最快的方法:

int main() {
    // x is the double we want to round
    double x = 100000000005.0;
    double y = log10(x) - 7.0;
    float a = pow(10.0, y);
    float b = (float)x;

    //c the closest round up float
    float c = a + b;
    printf("%.12f %.12f %.12f\n", c, b, x);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

Aki*_*nen 6

如果浮子较大,简单地为浮子和背部分配一个双重应该告诉我们.如果不是,则应该简单地将浮动增加一个单位.(对于正浮标).如果这仍然没有产生预期的结果,那么double大于float所支持的,在这种情况下float应该被赋给Inf.

float next(double a) {
    float b=a;
    if ((double)b > a) return b;
    return std::nextafter(b, std::numeric_limits<float>::infinity());
}
Run Code Online (Sandbox Code Playgroud)

[ Hack ] next_after的C版本(在选定的架构上)

float next_after(float a) {
    *(int*)&a += a < 0 ? -1 : 1;
    return a;
}
Run Code Online (Sandbox Code Playgroud)

更好的方法是:

float next_after(float a) {
   union { float a; int b; } c = { .a = a };
   c.b += a < 0 ? -1 : 1;
   return c.a;
}
Run Code Online (Sandbox Code Playgroud)

这两种自制黑客都忽略了Infs和NaN(仅适用于非负浮动).数学基于以下事实:浮点数的二进制表示是有序的.为了获得下一个可表示的浮点数,只需将二进制表示增加一.