代码之家  ›  专栏  ›  技术社区  ›  Shiro

php浮点计算2个小数点

  •  16
  • Shiro  · 技术社区  · 16 年前

    $a = 34.56
    
    $b = 34.55
    

    $a

    $b 正在四舍五入到最接近的0.05以获得此数字

    发生的是

    $c = $b - $a
    

    $c

    我试着用 number_format($c, 2) ,但输出为0.00,

    我怎样才能确定 b美元 正好是2位小数,后面没有隐藏的数字。

    据我所知, number_format 只能格式化显示,但值不是真正的2位小数,

    我希望我能从这里得到帮助。这让我很沮丧。

    7 回复  |  直到 6 年前
        1
  •  61
  •   aksu    12 年前

    尝试 sprintf ("%.2f", $c);

    浮点数在IEEE表示法中以2的幂表示,因此终止十进制数可能不是终止二进制数,这就是为什么会得到尾随数字。

    正如可变长度编码器所建议的那样,如果你知道你想要的精度,并且精度不变(例如,当你处理货币时),那么最好只使用定点数字,即将数字表示为美分而不是美元

    $a = 3456;
    
    $b = 3455;
    
    $c = $b - $a;
    
    sprintf ("%.2f", $c/100.0);
    

    这样,如果在打印前进行大量计算,就不会有任何舍入错误。

        2
  •  16
  •   cletus    16 年前

    使用 round() :

    $c = round($b - $a, 2);
    

    您还可以根据需要选择舍入模式。

    编辑: sprintf() 他在做什么 number_format() 不是:

    $c = number_format($b - $a, 2);
    

    $c = sprintf("%.2f", $b - $a);
    

        3
  •  5
  •   Robert L    16 年前

    通过使用bcmath库,您可以非常巧妙地避开所有这些问题。

        4
  •  4
  •   PHP from Bulgaria    13 年前

    本机计算:

    $a = 34.56;
    $b = 34.55;
    $c = $b - $a; // -0.010000000000005    
    

    工作如期(!始终使用BC函数进行实数计算,这一问题适用于所有基于C的平台):

    $a = '34.56';
    $b = '34.55';
    $c = bcsub($b, $a, 4); // -0.0100    
    
        5
  •  4
  •   jtaz    12 年前

    我最近在使用浮动进行计算时也遇到了这个问题。例如,我有两个浮点数,当减去并格式化时,其值为-0.00。

    $floatOne = 267.58;
    $floatTwo = 267.58;
    $result = number_format($floatOne - floatTwo, 2);
    print $result; //printed a string -0.00
    

    我所做的是:

    $result = abs($floatOne - $floatTwo);// Made the number positive
    print money_format('%i', $result); // printed the desired precision 0.00
    

    在我的解决方案中,我知道floatOne永远不会小于floatTwo。 这个 money_format 函数仅在系统具有strfmon功能时定义,而Windows没有。

        6
  •  3
  •   Variable Length Coder    16 年前

    你遇到了一个浮点数陷阱;它们不能总是表示精确的小数。如果需要精确的十进制值,最好使用整数,然后在最后除以所需的精度。

    例如,如果您使用代表美元(或您喜爱的货币)的浮动进行计算,您可能希望实际使用整数美分进行计算。

        7
  •  3
  •   Selay    11 年前

    如果仍然有人遇到类似的问题,浮点数减法会导致错误或奇怪的值。 不同的操作系统和不同版本的编程语言可能表现出不同的行为。

    它与PHP没有直接关系,也不是一个bug。 然而,每个程序员都应该意识到这个问题。

    20年前,这个问题甚至夺去了许多人的生命。

    1991年2月25日,MIM-104爱国者导弹连的浮点数计算问题使其无法在沙特阿拉伯的达兰拦截来袭的飞毛腿导弹,导致美军第14军需分队28名士兵死亡。

    但为什么会这样?

    在任何处理后都不具有相同的字符串表示形式。它也 无需任何数学运算即可打印。

    举个简单的例子:

    $a = '36';
    $b = '-35.99';
    echo ($a + $b);
    

    你会希望它打印0.01,对吗? 但是它会打印一个非常奇怪的答案,比如0.00999999998

    由于缺少足够的空间,十进制数不能很好地用二进制表示。所以,uou不能精确地表示1/3,因为它是0.3333333…,对吗?为什么我们不能将0.01表示为二进制浮点数也是出于同样的原因。1/100是0.000000 1010001110101110000。。。。。重复1010001110101110000。

    如果0.01以简化和系统截断的形式保存在二进制的01000111101011100001010中,当它被翻译回十进制时,它的读数将类似于0.0099999。。。。取决于系统(64位计算机将比32位计算机提供更好的精度)。在这种情况下,操作系统决定是按它所看到的方式打印,还是以更便于人阅读的方式打印。因此,他们希望如何表示它取决于机器。但它可以通过不同的方法在语言级别得到保护。

    这是因为在这种情况下,您指示应该如何读取它以及您需要的精度。

    推荐文章