通常,四舍五入到小数点2位是非常容易的
printf("%.2lf",<variable>);然而,舍入系统通常会舍入到最接近的,甚至。例如,
2.554 -> 2.55
2.555 -> 2.56
2.565 -> 2.56
2.566 -> 2.57我想要实现的是
2.555 -> 2.56
2.565 -> 2.57实际上,舍入半向上的在C中是可行的,但只适用于整数;
int a = (int)(b+0.5)因此,我要求如何做上面提到的同样的事情,在正值上小数点2位,而不是整数,以实现我前面所说的打印的。
发布于 2014-08-03 19:37:43
目前还不清楚你是否真的想要“四舍五入”,或者更确切地说是“从零到一半”,这就要求对负值进行不同的处理。
单精度二进制float精确到至少6位小数位,double精确到20位,因此DBL_EPSILON (在Float.h中定义)推到FP值将导致printf( "%.2lf", x )对n.nn5值的下一个100位。而不影响值的显示值,而不是n.nn5。
double x2 = x * (1 + DBL_EPSILON) ; // round half-away from zero
printf( "%.2lf", x2 ) ;对于不同的四舍五入行为:
double x2 = x * (1 - DBL_EPSILON) ; // round half-toward zero
double x2 = x + DBL_EPSILON ; // round half-up
double x2 = x - DBL_EPSILON ; // round half-down发布于 2014-08-03 18:22:40
编辑OP澄清,只有打印值需要四舍五入到小数点2位。
OP认为数字的四舍五入是“半途而废”或“从零到零”或“远离零”,这是误导性的。在0.005,0.015,0.025,0.995等100个“中途”数字中,只有4个是典型的“中途”:0.125,0.375,0.625,0.875。这是因为浮点数格式使用基-2,而像2.565这样的数字不能精确表示.
相反,像2.565这样的示例数字作为假定binary64的2.564999999999999947...的最接近的double值。将这一数字相加到最近的0.01应该是2.56,而不是执行部分所希望的2.57。
因此,只有数字以0.125和0.625的面积结束,正好是一半,并且是四舍五入,而不是像OP所期望的那样上升。建议接受并使用:
printf("%.2lf",variable); // This should be sufficient为了接近OP的目标,数字可能会被A(以0.125或0.625或B结尾)测试)略有增加。最小的增长将是
#include <math.h>
printf("%.2f", nextafter(x, 2*x));在@Clifford中还发现了另一种推拿方法。
前一个答案将一个double舍入到最近的double倍数为0.01。
典型的浮点格式使用像binary64这样的格式,它使用基-2。“四舍五入到最近的数学0.01,并与0.0相加”是一项挑战。
正如@Pascal所提到的,像2.555这样的浮点数通常只在2.555附近,并且有一个更精确的值,比如2.555000000000000159872...,而不是半途而废。
@BLUEPIXY解决方案是最好和实用的。
x = round(100.0*x)/100.0;圆周函数以浮点格式将其参数绕到最近的整数值,将大小写与零相舍五入,而不考虑当前的舍入方向。C11dr§7.12.9.6.
((int)(100 * (x + 0.005)) / 100.0)方法有两个问题:对于负数(OP没有指定),它可能绕错方向,整数的范围通常比double小得多(INT_MIN到INT_MAX)。
在某些情况下,比如当double x = atof("1.115");接近1.12时,它实际上应该是1.11,因为作为double,double确实更接近1.11,而不是“半途而废”。
string x rounded x
1.115 1.1149999999999999911182e+00 1.1200000000000001065814e+00假设为y = -f(-x),OP没有指定负数的舍入。
发布于 2014-08-03 23:51:27
下面是将double舍入最近的0.01 double的精确代码。
像x = round(100.0*x)/100.0;这样的代码函数,除了处理使用操作以确保精确地完成100.0的缩放之外,还没有造成精度损失。
这可能是比OP感兴趣的代码更多的代码,但它确实有效。
它适用于整个double范围-DBL_MAX到DBL_MAX。(仍然应该做更多的单元测试)。
它依赖于FLT_RADIX == 2,这是很常见的。
#include <float.h>
#include <math.h>
void r100_best(const char *s) {
double x;
sscanf(s, "%lf", &x);
// Break x into whole number and fractional parts.
// Code only needs to round the fractional part.
// This preserves the entire `double` range.
double xi, xf;
xf = modf(x, &xi);
// Multiply the fractional part by N (256).
// Break into whole and fractional parts.
// This provides the needed extended precision.
// N should be >= 100 and a power of 2.
// The multiplication by a power of 2 will not introduce any rounding.
double xfi, xff;
xff = modf(xf * 256, &xfi);
// Multiply both parts by 100.
// *100 incurs 7 more bits of precision of which the preceding code
// insures the 8 LSbit of xfi, xff are zero.
int xfi100, xff100;
xfi100 = (int) (xfi * 100.0);
xff100 = (int) (xff * 100.0); // Cast here will truncate (towards 0)
// sum the 2 parts.
// sum is the exact truncate-toward-0 version of xf*256*100
int sum = xfi100 + xff100;
// add in half N
if (sum < 0)
sum -= 128;
else
sum += 128;
xf = sum / 256;
xf /= 100;
double y = xi + xf;
printf("%6s %25.22f ", "x", x);
printf("%6s %25.22f %.2f\n", "y", y, y);
}
int main(void) {
r100_best("1.105");
r100_best("1.115");
r100_best("1.125");
r100_best("1.135");
r100_best("1.145");
r100_best("1.155");
r100_best("1.165");
return 0;
}https://stackoverflow.com/questions/25104883
复制相似问题