四舍五入
这种方法小学的时候就学过,它虽然简单,但是产生误差累计的因素还是很明显的。
就拿保留整数来说:
小数部分从0.0~0.4999,是属于“舍”的范围,产生的误差就是0.0~0.4999;
而小数部分0.5~0.9999,是属于“入”的范围,产生的误差就是0.5~0.0001。
在此就可以看出,两者的误差是不均等的,“入”的误差稍大。
因此,一个运算式子,如果其中经过了多次的四舍五入,产生的误差一般来说是难以互相抵消的。
四舍六入五成双
其实,就一位小数来说,舍去 0.0 是不存在误差的;只有 0.1~0.4、0.5、0.6~0.9 这 9 个数字舍入存在误差的问题。
那么就可以把“0.1~0.4”这 4 个数字舍去,把“0.6~0.9”这 4 个数字入上,由此产生误差的概率将是相同的,在大量计算时可以抵消误差。
而对于0.5,无论是是舍,还是入,都会有出现最大的舍入误差。
从概率上说,这个 0.5,应该有 50% 的概率是舍去,有 50% 的概率是入,以争取在大量计算时误差互相抵消。
这个就可以看 0.5 前面的位了,如果是奇数,就入上,如果是偶数,就舍去这个 0.5。
例如:把下列数字,保留两位小数。
1.265,末尾的 5,要根据前面的 6,舍,结果是:1.26;
1.275,末尾的 5,要根据前面的 7,入,结果是:1.28;
1.285,末尾的 5,要根据前面的 8,舍,结果是:1.28;
1.295,末尾的 5,要根据前面的 9,入,结果是:1.30。
这就是“银行家舍入算法(Banker's rounding)”,可以说成:四舍六入五成双。
采用普通的四舍五入,还是采用“四舍六入五成双”,结果的数字相差并不大,但是技术水平的层次就大不相同了。
这两种舍入的算法,在C语言里面,没有现成的函数,需要我们自己编写。
在高版本的 VB 等语言中,含有了 Round 函数,这是使用“四舍六入五成双”算法的舍入函数。
有人拿“四舍五入”的人工计算来验证 Round 函数,结果竟然认为是 Round 函数算错了,呵呵
可见:
”
【问】PASIC四舍五入函数?PC的四舍五入函数和格式!
【答】输出的话是writeln(a:0:x);其中x是保留多少位。函数是round(a);四舍五入到整数,但是这个函数写的有点问题,例如4.5会四舍五入成4,不建议使用。
“
DS18B20 的温度数据与显示
DS18B20 是温度测量器件,用两字节数据给出温度的摄氏度数值,单位是(1/16)度,或者说是0.0625℃。
如果现场的温度大约在 22~23 ℃之间,DS18B20 给出的数据,换算出十进制,将是如下 16 个数字:
22.0000
22.0625
22.1250
22.1875
22.2500
22.3125
22.3750
22.4375
22.5000
22.5625
22.6250
22.6875
22.7500
22.8125
22.8750
22.9375
精度真够高的!
DS18B20 的分辨率达到了万分之五,有四位小数。
在一般计算、显示时,保留一、二位小数即可。
但是,在网上看到了很多关于 DS18B20 的网文,都没有认真处理小数。
甚至有些销售的成品的单片机开发板,只是保留了整数进行显示,诺大的小数部分,都忽略了!
呵呵,真是暴殄天物,白白浪费了18B20 如此高的精密度!
有些人的程序采用了“加0.5再取整”的方法,这是按照“四舍五入”处理的,马马虎虎的,也算可以了。
“四舍六入五成双”在单片机方面的应用
做而论道已经针对采用“四舍六入五成双”进行舍入的算法,编写出了C语言的函数。
程序并不长,也不难编写,但是不想公布代码了,掌握C语言的网友都可以自行编写。