V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xing393939
V2EX  ›  PHP

PHP的浮点运算的问题

  •  
  •   xing393939 · 2013-01-22 18:55:44 +08:00 · 3698 次点击
    这是一个创建于 4316 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <?php
    $x1 = 80.89;
    $x2 = 81.88;

    $x = $x1;
    while($x <= $x2) {
    $x += 0.01;
    echo $x;
    echo '<br />';
    }

    运行看最后2行结果,如何解释?
    把$x1的值调大一点又正常了
    11 条回复    1970-01-01 08:00:00 +08:00
    PrideChung
        1
    PrideChung  
       2013-01-22 19:45:40 +08:00
    PHP的浮点数存在精度问题(其实很多编程语言都有),如果你不停地对一个变量进行浮点数运算,误差就会积累,直到显示出来。运行一下下面的脚本,道理都是一样的。如果你需要更高精度的浮点数运算,请使用bcmath库。

    <?php
    $i = 0;
    while($i < 10) {
    $i+=0.001 ;
    echo $i . '<br />';
    }
    laoyuan
        2
    laoyuan  
       2013-01-22 19:49:10 +08:00
    手册 - 语言参考 - 类型 - 浮点型,你会找到答案。你可以用var_dump看各变量都是什么值。

    通俗的说,在php里,浮点型在运算时是一个近似值。
    laoyuan
        3
    laoyuan  
       2013-01-22 19:50:24 +08:00
    可能每一个学习PHP的人都遇到过这问题吧,我搞明白这东西大概花了两个晚上。
    zhangxiao
        4
    zhangxiao  
       2013-01-22 19:54:19 +08:00
    计算机的二进制无法精确的表示浮点数的,小数都被近似于一个能被表示成:
    0.5+0.25+0.125+... 这么一个值,当然这里的加项不一定都出现,取决于具体数值了。其实和整数部分一个道理: 1+2+4+8...
    Sunyanzi
        5
    Sunyanzi  
       2013-01-22 19:56:07 +08:00
    这是计算机的老毛病了 ... 计算机内部数值以二进制存储 ...

    而在十进制下面的有限小数转化为二进制之后可能就是无限小数 ...

    显而易见计算机没办法存储无限位的数字 ...

    所以这导致了有些浮点数没办法精确的转换为二进制才造成误差 ...
    laoyuan
        6
    laoyuan  
       2013-01-22 20:00:53 +08:00
    我觉得智能一点的语言应该按人的思维习惯将整数部分和小数部分分成两个整型保存。。。。
    luikore
        7
    luikore  
       2013-01-22 20:44:32 +08:00
    1.4+1.7 得到两种答案: 3.0999999999999996 和 3.1, 哪个更精确?

    答案是前者, 因为有效数字更多...
    sNullp
        8
    sNullp  
       2013-01-22 20:51:18 +08:00
    @laoyuan 。。。只能说最原始的语言想的都比你远。。看看浮点数的规范吧
    clowwindy
        9
    clowwindy  
       2013-01-22 20:53:01 +08:00
    如果你的需求是算钱,用整型吧……
    xcl3721
        10
    xcl3721  
       2013-01-23 12:07:32 +08:00
    bcmath看看,听说金融都用这个插件算
    bombless
        11
    bombless  
       2013-01-23 13:14:14 +08:00
    噗,各位不了解的可以去了解下IEEE754是什么……这完全不是PHP的问题。

    精度损失其实很常见,只不过你用的十进制小数表示法有时候把这个问题凸显出来了于是你就不淡定了……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1714 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 16:54 · PVG 00:54 · LAX 08:54 · JFK 11:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.