5

我想使用 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;
}

谢谢你。

4

3 回答 3

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

这两种自制的 hack 都忽略了 Infs 和 NaNs(并且仅适用于非负浮点数)。数学基于这样一个事实,即浮点数的二进制表示是有序的。要获得下一个可表示的浮点数,只需将二进制表示加一即可。

于 2013-03-08T13:00:56.043 回答
4

如果你使用,你可以使用 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;
}
于 2013-03-08T13:02:27.893 回答
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(它适用于任何结果)

于 2013-03-08T13:04:48.257 回答