十进制小数与二进制小数相互转换
2016-12-26 16:53 ZengGW 阅读(1664) 评论(0) 编辑 收藏 举报一、十进制小数转二进制小数的方法
今天看到鸟哥的一篇博客,里边说的额是浮点数的问题,结果里边的小数转换成二进制数我就闹不明白,通过在网上查询,知道咋回事了,先上一段代码(随便写的):
/** * 十进制小数转二进制小数的方法 * @param $decimal 操作的小数(比如:0.75,0.57等) * @param $bit 位数保留多少位二进制数 * @return [type] $binary (小数的二进制数) */ function getBinaryDecimal($decimal = 0,$bit = 32){ if(!is_numeric($decimal))exit('参数错误!'); $binary = ''; //返回的二进制数 $base = $decimal; //记录计算的基数(以此为终止循环条件) $i = 0; //控制二进制数的位数,因为可能无穷无尽,所以只能尽可能的接近 while($base != 0 && $i++ < $bit){ $tmp = 0; //记录每一次计算的结果 $tmp = $base * 2; if($tmp >= 1){ $base = $tmp - 1; $binary .= 1; }else{ $base = $tmp; $binary .= 0; } } //返回用户需要的指定位数 return $binary; }
上面的函数写的有点简陋,只是针对小数部分,差不多就那么个意思,接下来我就说下小数转二进制数的计算方式,通过上面的函数也不难看出:
例一:0.6(用小数去乘2,得到的结果大于1的,二进制数在该位就是1,然后用结果减去1剩下的小数继续执行上一步操作,直到结果为0)
计算表达式 结果 二进制数 剩余小数(结果)
0.6 * 2 1.2 1 0.2(1.2 - 1)
0.2 * 2 0.4 0 0.4
0.4 * 2 0.8 0 0.8
0.8 * 2 1.6 1 0.6(1.6 - 1)
.......... ..... ... .....
例二:0.75
计算表达式 结果 二进制数 剩余小数(结果)
0.75 * 2 1.5 1 0.5(1.5 - 1)
0.5 * 2 1 1 0(1 - 1)
结果0.75的二进制数为0.11
一直这样计算下去,直到剩余的结果为0时,才算计算结束,然后把二进制数拼接起来就是该小数对应的二进制数了,例一会无限循环下去,例二则不会;
其实上面的例子只是我们自己的理想算法,真正在程序中就算的结果可能回是 "0.49999999999999"而不是0.5,这样的话0.75的二进制数也将是无穷无尽的;
注意:可能一直计算下去会出现无穷无尽,所以我加了一个位数来控制,只能尽可能的接近值,而不能说一定准确的得到一个小数的二进制数
二、二进制小数转十进制小数的方法
上面咱们已经讨论了如何将十进制小数转换成二进制小数,就是不断的*2,然后跟1比较来取二进制位的值,然后根据把剩余的值继续乘于2,一直循环,知道结果为0时为止,那么二进制小数如何转换成十进制的小数呢?接下来咱们就来看看
例一:把二进制数0.11转换成十进制小数
(0.11)2 = 0 * 20 + 1 * 2-1 + 1 * 2-2
= 0 + 0.5 + 0.25
= 0.75
以上就是计算的方式,小数点后的数字从-1开始,一直计算下去,下面是我随便写的两句代码:
/** * 二进制小数转十进制小数的方法 * @param $binary 需要计算的二进制数 * * @return [type] $result */ function getDecimalResult($binary){ if(!$binary)exit('参数错误!'); //获取数组数量 $binary = str_split($binary); $binary_count = count($binary); //结果 $result = 0; $i = 0; while($i < $binary_count){ //计算结果 $result += $binary[$i] * pow(2,-($i+1)); $i++; } return $result; }
以上就是二进制小数和十进制小数相互转换的方法,写的不好希望大家多多指正,谢谢!