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

时间:2013-03-08 12:30:13

标签: 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;
}

谢谢。

3 个答案:

答案 0 :(得分: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());
}

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

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(仅适用于非负浮动)。数学基于以下事实:浮点数的二进制表示是有序的。要获得下一个可表示的浮点数,只需将二进制表示增加一个。

答案 1 :(得分:3)

如果您使用,则可以使用nextafterf功能。

#include <stdio.h>
#include <math.h>
#include <float.h>

int main(){
  // x is the double we want to round
  double x=100000000005.0;

  float c = x;

  if ((double)c <= x)
    c = nextafterf(c, FLT_MAX);

  //c the closest round up float
  printf("%.12f %.12f\n",c,x);
  return 0;
}

答案 2 :(得分:3)

C有一个很好的nextafter函数,可以在这里提供帮助;

float toBiggerFloat( const double a ) {
    const float test = (float) a;
    return ((double) test < a) ? nextafterf( test, INFINITY ) : test;
}

这是一个测试脚本,它在所有类别的数字上显示它(正/负,正常/次正常,无限,nan,-0):http://codepad.org/BQ3aqbae(它可以在任何结果上正常工作)