我想使用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;
}
谢谢。
答案 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)
如果您使用c99,则可以使用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(它可以在任何结果上正常工作)