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

关于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);
时间: 2024-10-03 12:14:17

为什么php的浮点数运算不准确的相关文章

JavaScript 浮点数运算 精度问题_javascript技巧

Js代码 复制代码 代码如下: <script type="text/javascript" language="javascript"> alert(1/3);//弹出: 0.3333333333333333 alert(0.09999999 + 0.00000001);//弹出: 0.09999999999999999 alert(-0.09999999 - 0.00000001);//弹出: -0.09999999999999999 alert(0

Java简单类型进行精确浮点数运算

运算 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精确的浮点数运算,包括加减乘除和四舍五入. 以下为代码: import java.math.BigDecimal; public class Arith { //默认除法运算精度 private static final int DEF_DIV_SCALE = 10; //这个类不能实例化 private Arith(){ } /** * 提供精确的加法运算. * @param v1 被加数 * @param v2 加数 *

计算机-浮点数运算的问题 (3.14+le20)-le20=0.00?

问题描述 浮点数运算的问题 (3.14+le20)-le20=0.00? 昨天老师上课<程序设计与计算机系统>中说道:(3.14+le20)-le20=0.00,而le20-le20+3.14=3.14, 对前答案的解释是:浮点数在运算时,会有一个对齐问题,这样在非常大的数和3.14相加时,会舍掉有效位,然后只剩le20了,听得不懂而且也没查到资料,所以到这里来求大神来了!先谢了! 解决方案 是的,浮点数有特殊的存储方式,你可以看一下关于浮点数的存储资料,或许能明白一些,维基中有

php中让人头疼的浮点数运算分析_php技巧

本文实例分析了php中让人头疼的浮点数运算.分享给大家供大家参考,具体如下: 在做电商的时候,计算价格是免不了的,然后发现了php的一个坑,口算应该正确的值,php运算出来会跟你不一样 请看下面的代码: $price=69.1; $count=100; $total=$price*$count-6910; echo $total; 你猜一下变量$total的值是多少,运行一下这个代码输出:-9.09494701773E-13 怎么解决这个问题呢? 使用round函数 代码修改成: $price=

php中浮点数运算常见问题

本文实例分析了php中让人头疼的浮点数运算.分享给大家供大家参考,具体如下: 在做电商的时候,计算价格是免不了的,然后发现了php的一个坑,口算应该正确的值,php运算出来会跟你不一样 请看下面的代码: $price=69.1; $count=100; $total=$price*$count-6910; echo $total; 你猜一下变量$total的值是多少,运行一下这个代码输出:-9.09494701773E-13 怎么解决这个问题呢? 使用round函数 代码修改成: $price=

多线程如何克服浮点数计算不准确的缺点?

问题描述 多线程如何克服浮点数计算不准确的缺点? 多线程浮点数的累加和求均方差,如何克服浮点数计算不准确的缺点,计算结果存在不确定性怎么解决? 解决方案 浮点数存在存储的精度误差和进制转换误差,如果你要提高精度,可以考虑用字符数组模拟手工十进制计算,但是性能会比较低. 解决方案二: 那要看你是什么语言,什么开发环境了?在java中,有一个BigDecimal可以提供精确的数值计算的.

DSP中浮点转定点运算--定点数模拟浮点数运算及常见的策略_C 语言

4.定点数模拟浮点数运算及常见的策略 相信大家到现在已经大致明白了浮点数转换成定点数运算的概貌.其实,原理讲起来很简单,真正应用到实际的项目中,可能会遇到各种各样的问题.具我的经验,常见的策略有如下几条: 1)除法转换为乘法或移位运算 我们知道,不管硬件平台如果变换,除法运算所需要的时钟周期都远远多于乘法运算和加减移位运算,尤其是在嵌入式应用中,"效率"显得尤为重要.以笔者的经验,其实,项目中的很大一部分除法运算是可以转换成乘法和移位运算,效率还是有很大提升空间的. 2)查表计算 有些

Java中使用BigDecimal进行浮点数运算_java

最近研究了一下Java的浮点数计算问题,从网上查询了相关的资料,汇总并经过了一些整理和调试,最后完成此文,欢迎大家指出其中的错误和问题. 在Java中,float声明的变量是单精度浮点数,double声明的变量是双精度浮点数,顾名思义就是double型的实体占用内存空间是float的两倍.float是4个字节而double是8个字节.float和double类型的数据,无法精确表示计算结果,这是由于float和double是不精确的计算.大家可以通过下面代码可以看出来: 复制代码 代码如下: p

解决JS浮点数运算出现Bug的方法_javascript技巧

37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998 怎么会这样,两个只有一位小数的数字相乘,怎么可能多出这么小数点出来. 我Google了一下,发现原来这是JavaScript浮点运算的一个bug. 比如:7*0.8 JavaScript算出来就是:5.6000000000000005 网上找到了一些解决办法,就是重新写了一些浮点运算的函数或直接扩大倍数运算. 下面就把这