çprintf的浮动四舍五入 [英] C printf float rounding

查看:150
本文介绍了çprintf的浮动四舍五入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不得不重新实现的printf(3) C 不使用,会做这种转换我任何功能

I have to reimplement printf(3) with C without using any function that would do the conversion for me.

我几乎做我只需要%A 键,它也几乎多亏做你们:的如何在%printf语句转换工作?

I'm nearly done I just need %a and it's also nearly done thanks to you guys : How %a conversion work in printf statement?

该男子说:

双参数为圆润并转换为十六进制
  在款式[ - ] 0xh.hhhp [+ - ] d,其中数字后面的数字
  十六进制点字符等于precision规范。

The double argument is rounded and converted to hexadecimal notation in the style[-]0xh.hhhp[+-]d, where the number of digits after the hexadecimal-point character is equal to the precision specification.

所以我的问题是的圆形如何

我发现: printf的舍入双打行为

和它解释了printf的是使用的银行家圆圆形一半甚至的,但我不知道如何来实现它,我已经试过这样:

And it explains that printf is using banker round or Round half to even but I have no idea how to implement it I have tried this:

a_double = round(a_double * pow(10, precision)) / pow(10, precision)

但在百万 0.000001 启动和添加测试 0.000001 每次失败 405201 倍,例如用 0.000011

But on 1000000 tests starting from 0.000001 and adding 0.000001 each time it fails 405201 times, for example with 0.000011:

printf("%.6a", 0.000011) => 0x1.711948p-17
myprintf("%.6a", 0.000011) => 0x1.711947p-17

舍入'失败',我没有得到相同的值作为真正的printf。

The rounding 'failed' and I didn't get the same value as the real printf.

我不认为这变换算法双击六记法是错误的,因为以$ 13 的对$ pcision我绝对没有错误。

I don't think that the algorithm that transforms the double to hexa notation is wrong because with a precision of 13 I have absolutely no errors.

所以,我只是想知道如何我可以做同样的舍入的printf 确实在

So I just would like to know how I could do the same rounding that printf does on the double.

推荐答案

好了,我想我的previous算法并没有完全实现四舍五入所以让我们来看看结果如何四舍五入。我会用你的例子号码作为我的榜样人数太多。首先,我们发现,0.000011 /(2 ^( - 17))= 0.000011 *(2 ^ 17)= 1.441792所以电源是-17。然后,我们输出1,从1.441792减1和16相乘,给人7.068672。我们输出7,从中减去7和16相乘,给人1.09875199999999。我们输出1,从中减去1和16相乘,给人1.58003199999985。我们输出1,从中减去1和16相乘,给人9.28051199999754。然后输出9,减9,由16乘,其结果是4.48819199996069。我们输出4,减去4,由16乘,其结果是7.81107199937105

Ok, so I guess my previous algorithm didn't fully implement rounding so let's take a look how the result could be rounded. I'll use your example number as my example number too. First, we find that 0.000011/(2^(-17)) = 0.000011*(2^17) = 1.441792 so the power is -17. Then, we output "1.", subtract 1 from 1.441792 and multiply it by 16, giving 7.068672. We output 7, subtract 7 from it and multiply by 16, giving 1.09875199999999. We output 1, subtract 1 from it and multiply by 16, giving 1.58003199999985. We output 1, subtract 1 from it and multiply by 16, giving 9.28051199999754. Then output 9, subtract 9, multiply by 16, the result is 4.48819199996069. We output 4, subtract 4, multiply by 16, the result is 7.81107199937105.

现在,我们要输出的最后一个字符。现在我们要做的魔力。因为7.81107199937105比至7中,我们输出8更接近8。这神奇的只对最后一个字符做。对于非最后字符,整数部分始终使用和小数部分未在确定的字符,以输出在所有使用的。然后,在此之后,我们输出P-17,因为功率为-17。

Now, we're going to output the last character. Now we do the magic. Because 7.81107199937105 is closer to 8 than to 7, we output "8". This magic is done only for the last character. For the non-last characters, the integral part is always used and the fractional part is not used at all in determining which character to output. Then, after this, we output "p-17" because the power was -17.

请注意,该通常的舍入规则说,7.5这是同样接近既7和8被舍入为8,而不是7和6.5将被舍入到7,而不是6。然而,如果要执行的轮一半甚至和你遇到如6.5则取整到6,因为6是偶数和7不是。我不知道,如果你发现对银行家轮也适用于%A,你唯一可以做的就是测试实现各种舍入算法,看看可以得到相同的结果作为真正%一个printf的。应该不会太难,因为不同的舍入算法只是一半的处理方式不同。其余部分被舍入到最接近的数

Note that the usual rounding rules say that 7.5 which is equally close to both 7 and 8 is rounded to 8, not to 7 and 6.5 would be rounded to 7, not to 6. However, if you want to implement the round half to even and you encounter e.g. 6.5 then it is rounded down to 6 because 6 is even and 7 is not. I'm not sure if what you found about the banker round applies also to %a, the only thing you can do is to test implementing various rounding algorithms and see which gives the same results as the real %a of printf. Shouldn't be that hard because the different rounding algorithms just differ on how half is handled. The rest is rounded to the closest number.

,我错在你的previous问题(如何%在printf语句转换工作?中)中说,为3.2具有非圆形重新presentation 1.999999 .... p + 1和圆形重新presentation 1.99999ap +1最后的A会出现因有限浮点precision。当然,它的发生是由于舍入,而不是由于有限浮点precision,正如你可能已经通过,现在实现的。

By the way, I was wrong in your previous question (How %a conversion work in printf statement?) in saying that for 3.2 which has the non-rounded representation 1.999999....p+1 and the rounded representation 1.99999ap+1 the last "a" would occur due to limited floating point precision. Of course it occurs due to rounding and not due to limited floating point precision, as you probably have realized by now.

这篇关于çprintf的浮动四舍五入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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