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

这是一个 PHP 的 整数 浮点数转换 bug?

  •  
  •   haha512 · 2023-07-08 22:44:54 +08:00 · 1672 次点击
    这是一个创建于 496 天前的主题,其中的信息可能已经有所发展或是发生改变。
    
    // php 8.0 - 8.2 
    // floatval  函数用于获取变量的浮点值  
    // intval() 函数用于获取变量的整数值。
    
    php -r 'echo floatval("2.51");'  >> 2.51
    
    php -r 'echo floatval(2.51);'		>>2.51
    
    php -r 'echo intval(251);'		>> 251
    php -r 'echo intval("251");'	>> 251
    
    
    php -r 'echo floatval("2.51")*100;'	>> 251
    
    php -r 'echo floatval(2.51)*100;'	>> 251
    
    
    
    
    // bug 来了 floatval("2.51")*100 根据上面可知是 251 ,也可知 intval(251)===251
    php -r 'echo (int)( floatval("2.51")*100 );'	>> 250
    php -r 'echo intval( floatval("2.51")*100 );'	>>250
    
    
    
    

    12 条回复    2023-07-10 11:03:06 +08:00
    churchill
        2
    churchill  
       2023-07-08 23:01:53 +08:00
    不算 bug 吧
    大部分语言的取整实现都是 truncate towards zero
    250.999999 ~取整可不就是 250 嘛
    veike
        3
    veike  
       2023-07-09 01:37:35 +08:00
    php -r 'echo (int) bcmul("2.51", "100");' 结果为 251
    mingl0280
        4
    mingl0280  
       2023-07-09 08:02:41 +08:00
    建议楼主回去复习 IEEE-754 浮点数。
    这属于浮点数的基本知识了,浮点数不是精确等于某个值的。
    darkengine
        5
    darkengine  
       2023-07-09 10:02:19 +08:00
    不是语言的问题,基本上每个平台/语言都会遇到
    NessajCN
        6
    NessajCN  
       2023-07-09 10:13:35 +08:00
    Python:
    >>> 2.51*100
    250.99999999999997

    NodeJS:
    > 2.51*100
    250.99999999999997

    另外楼主可以试试经典的 0.1+0.2
    lysS
        7
    lysS  
       2023-07-09 11:14:45 +08:00
    0.251 应该不能用那几位二进制精确表示,用的是近似值
    llh880808
        8
    llh880808  
       2023-07-09 15:19:31 +08:00
    浮点数的表达范围为什么能远远大于整型数,这一定是有取舍的,舍去的就是精度

    浮点数的特点是在 0 附近的精度相当高,越靠近±无穷大精度就越差,可以想象当数字大到一定程度,(浮点数)连整数的精度都保证不了

    因此不要预期 2.51 (更靠近 0 )和 251 会有完全一致的行为
    zhangtest
        9
    zhangtest  
       2023-07-09 17:34:16 +08:00
    php 计算相关的用这个
    https://www.php.net/manual/zh/ref.bc.php
    well775397252
        10
    well775397252  
       2023-07-09 20:03:07 +08:00
    不是 bug
    woojanelook
        11
    woojanelook  
       2023-07-10 10:39:44 +08:00
    php 涉及浮点计算的都要使用 bc 函数
    Symo
        12
    Symo  
       2023-07-10 11:03:06 +08:00
    浮点数的 round floor ceil 还是通过 bcmath 的方式显式指定,依赖默认转换很容易出问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2918 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 07:20 · PVG 15:20 · LAX 23:20 · JFK 02:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.