我需要将具有系统精度的浮点数转换为打印输出具有指定精度(例如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);
请参阅 ideone/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 ideone/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
更多推荐
我怎么能四舍五入到一个给定的十进制精度
发布评论