我怎么能四舍五入到一个给定的十进制精度 [英] How can I round a float to a given decimal precision

查看:322
本文介绍了我怎么能四舍五入到一个给定的十进制精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将具有系统精度的浮点数转换为打印输出具有指定精度(例如3个小数位)的浮点数。 fprintf函数不能满足这个要求,因为它不会正确地舍入一些数字。我试过的所有其他解决方案都失败了,因为当我将其转换回浮点数时,它们都会重新引入不需要的精度。例如:

  float xf_round1_f(float input,int prec){

printf(%f \t,输入);
int trunc = round(input * pow(10,prec));
printf(%f\t,(float)trunc);
input =(float)trunc / pow(10,prec);
printf(%f \ n,输入);
return(input);




$ p
$ b

这个函数打印输入,截断的整数和输出到每一行,结果看起来像这样的一些数字应该被截断到小数点后三位:

49.975002 49975.000000 49.974998

49.980000 49980.000000 49.980000

49.985001 49985.000000 49.985001

49.990002 49990.000000 49.990002



49.995003 49995.000000 49.994999

50.000000 50000.000000 50.000000

您可以看到第二步按预期工作 - 甚至当trunc被强制转换为浮动打印时 - 但是只要我将其转换回浮点数,精度就会返回。第一行和第六行显示了问题情况。

当然,必须有解决这个问题的方法 - 即使第一行的结果仍然是49.975002, ,但在这种情况下,有一个真正的问题。

任何解决方案?

编辑:看来您可能只关心打印结果。 printf 通常足够聪明,可以对指定的位数进行适当的舍入。如果你的格式为%。3f,你可能会得到你所需要的。


如果您唯一的问题是 所需的数字,您可以通过将所有数字设置为高于所需数字来轻松解决问题。不幸的是,这增加了答案的绝对误差。即使是之前的确切结果,如 50.000 现在关闭。



只需将此行添加到结尾的函数:

pre $ input $ nextafterf(input,input * 1.0001);

请参阅 http://ideone.com/iHNTzs

  49.975002 49975.000000 49.974998 49.975002 
49.980000 49980.000000 49.980000 49.980003
49.985001 49985.000000 49.985001 49.985004
49.990002 49990.000000 49.990002 49.990005
49.995003 49995.000000 49.994999 49.995003
50.000000 50000.000000 50.000000 50.000004


I need to convert a floating-point number with system precision to one with a specified precision (e.g. 3 decimal places) for the printed output. The fprintf function will not suffice for this as it will not correctly round some numbers. All the other solutions I've tried fail in that they all reintroduce undesired precision when I convert back to a float. For example:

float xf_round1_f(float input, int prec) {

    printf("%f\t",input);
    int trunc = round(input * pow(10, prec));
    printf("%f\t",(float)trunc);
    input=(float)trunc / pow(10, prec);
    printf("%f\n",input);
    return (input);

}

This function prints the input, the truncated integer and the output to each line, and the result looks like this for some numbers supposed to be truncated to 3 decimal places:

49.975002 49975.000000 49.974998

49.980000 49980.000000 49.980000

49.985001 49985.000000 49.985001

49.990002 49990.000000 49.990002

49.995003 49995.000000 49.994999

50.000000 50000.000000 50.000000

You can see that the second step works as intended - even when "trunc" is cast to float for printing - but as soon as I convert it back to a float the precision returns. The 1st and 6th rows illustrate problem cases.

Surely there must be a way of resolving this - even if the 1st row result remained 49.975002 a formatted print would give the desired effect, but in this case there is a real problem.

Any solutions?

解决方案

Edit: it appears you may only care about the printed results. printf is generally smart enough to do proper rounding to the number of digits you specify. If you give a format of "%.3f" you will probably get what you need.


If your only problem is with the cases that are below the desired number, you can easily fix it by making everything higher than the desired number instead. Unfortunately this increases the absolute error of the answer; even a result that was exact before, such as 50.000 is now off.

Simply add this line to the end of the function:

input=nextafterf(input, input*1.0001);

See it in action at http://ideone.com/iHNTzs

49.975002   49975.000000    49.974998   49.975002
49.980000   49980.000000    49.980000   49.980003
49.985001   49985.000000    49.985001   49.985004
49.990002   49990.000000    49.990002   49.990005
49.995003   49995.000000    49.994999   49.995003
50.000000   50000.000000    50.000000   50.000004

这篇关于我怎么能四舍五入到一个给定的十进制精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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