将double舍入到最接近和更大的浮点数 [英] Round a double to the closest and greater float

查看:100
本文介绍了将double舍入到最接近和更大的浮点数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to round big double number (>1e6) to the closest but bigger float using c/c++. I tried this but I'm not sure it is always correct and there is maybe a fastest way to do that :

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;
}

谢谢.

推荐答案

简单地将一个double分配给float,然后应返回,以判断float是否更大.如果不是,则应仅将浮点数增加一个单位. (用于正浮点数).如果仍然不能产生预期的结果,则说明double值大于float所支持的大小,在这种情况下,应该将float分配给Inf.

Simply assigning a double to float and back should tell, if the float is larger. If it's not, one should simply increment the float by one unit. (for positive floats). If this doesn't still produce expected result, then the double is larger than supported by a float, in which case float should be assigned to Inf.

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

[ Hack ] next_after的C版本(在某些架构上)

[Hack] C-version of next_after (on selected architectures would be)

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

更好的方法是:

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

这两种自制的技巧都忽略了Infs和NaN(仅适用于非负浮点数).数学基于以下事实:浮点数的二进制表示形式是有序的.要进入下一个可表示的浮点数,只需将二进制表示形式加一即可.

Both of these self-made hacks ignore Infs and NaNs (and work on non-negative floats only). The math is based on the fact, that the binary representations of floats are ordered. To get to next representable float, one simply increments the binary representation by one.

这篇关于将double舍入到最接近和更大的浮点数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆