为什么php的浮点数运算不准确

简介: 例子: //例子 $a = 10.601; $b = 10.6009; echo $a- $b; // 结果如下 0.00010000000000154 结果错误,why? why 根本原因, 在某些情况下, 2 进制无法精确表示 10 进制的小数部分。

关于php浮点数,经常遇见预算不准确的情况

例子:

//例子
$a = 10.601;
$b = 10.6009;
echo $a- $b;

// 结果如下
0.00010000000000154

结果错误,why?

why

根本原因, 在某些情况下,
2 进制无法精确表示 10 进制的小数部分。

把 10 进制转化为 2 进制,需要进行如下换换算,下面以10.601为例

  • 整数部分

连续用该整数除以2,取余数,然后商再除以2,直到商等于0为止。然后把得到的各个余数按相反的顺序排列。简称"除2取余法"。

  • 小数部分

连续用改小数乘以2,取整数部分,然后小数部分再乘以2,直到小数部分为0为止 。然后把取出的整数部分按顺序排列。简称"乘2取整法"。

10 (整数部分)

 
10/2=5---------0
5/2=2----------1
2/2=1----------0
1/2=1----------1

(10) 10=(1010) 2


0.601 小数部分

0.601*2=1.202 ----1
0.202*2=0.404 ----0
0.404*2=0.808 ----0
0.808*2=1.616-----1
0.616*2=1.232-----1
0.232*2=0.464-----0
0.464*2=0.928-----0
......

(0.601)10 = (0.10011001......)2

我们发现会无限的循环下去,没法精确用2进制标识

php浮点数

浮点数,以64位的长度(双精度)为例, 会采用 1 位符号位(E), 11 指数位(Q), 52 位尾数(M)表示

  • 符号位:最高位表示数据的正负,0表示正数,1表示负数。
  • 指数位:表示数据以2为底的幂,指数采用偏移码表示
  • 尾数:表示数据小数点后的有效数字.

只能有52位存储0.601部分,这样大家就能看出原因了。

解决办法

采用 “bc 数据函数” http://php.net/manual/zh/ref.bc.php

$a = 10.601;
$b = 10.6009;
//echo $a- $b;

echo bcsub($a , $b,4);
目录
相关文章
PHP为什么需要字符串运算?底层原理是什么?
PHP为什么需要字符串运算?底层原理是什么?
|
PHP
PHP浮点数转int精度丢失?
PHP浮点数转int精度丢失?
543 0
|
PHP
PHP数学函数实践四:将浮点数从零舍入到指定的小数位数
哈喽~今天我将给大家继续之前的PHP数学函数实践系列的文章,那么在上一篇《PHP数学函数实践三:随机函数rand()的巧妙运用》中给大家介绍了怎么使用rand()函数,感兴趣的朋友可以学习了解~ 本文带来PHP数学函数实践四!主要内容则是讲解如何将浮点数从零舍入到指定的小数位数? 首先给大家简单介绍下PHP中的浮点数是什么? 浮点型(也叫浮点数 float,双精度数 double 或实数 real)可以用以下任一语法定义:
186 0
|
PHP
php浮点数计算比较及取整不准确解决方法
原文:php浮点数计算比较及取整不准确解决方法 php有意思的现象,应该是很多编程语言都会有这样的现象。这个是因为计算机的本身对浮点数识别的问题..... [php] view plaincopy   $f = 0.
1074 0
|
7月前
|
关系型数据库 MySQL PHP
PHP 原生操作 Mysql
PHP 原生操作 Mysql
81 0