【问题标题】:Error With Using (int) and (double) together to Cut off Decimals一起使用 (int) 和 (double) 来截断小数时出错
【发布时间】:2013-02-21 15:34:26
【问题描述】:

当我将 (int) 与 (double) 一起使用时,有时它无法正常工作。
查看 PHP 代码示例:

我需要留下 2 个小数并删除其他小数...

我知道 number_format();功能但我不能使用它。因为它是四舍五入的数字

number_format(24.299,2);
输出:24.30
我需要:24.29

<?php

$str="158.2";

echo (double)$str; // Output: 158.2
echo (double)$str*100; // Output: 15820
echo (int)((double)$str*100); // Output: 15819 <-WHY? It Must To Be 15820, Why 15819? 
echo ((int)((double)$str*100)/100); // Output: 158.19
?>

我需要在数字中保留两位小数,并在不四舍五入的情况下删去其他小数。

【问题讨论】:

    标签: php floating-point int double floating-point-precision


    【解决方案1】:

    由于浮点精度(例如,请参阅此问题:PHP - Floating Number Precision),158.2 * 100 不是完全 15820,而是类似于15819.99999999

    现在(int) 用于类型转换,不用于四舍五入,并且该点之后的所有数字都将被删除。

    我需要在数字中保留两位小数,并在不四舍五入的情况下删去其他小数。

    这很简单:

    number_format($str, 2);
    

    更新

    number_format圆,所以有点复杂:

    bcmul($str,100,0)/100
    

    bcmul 以任意精度相乘,在本例中为 0。结果:

    bcmul(158.2,100,0)/100 == 158.2
    bcmul(24.299,100,0)/100 == 24.29
    

    【讨论】:

      【解决方案2】:

      这并不能回答为什么会发生这种情况(它可能是一个精确错误),但要解决您的问题,请尝试使用 $foo = sprintf("%.2f", (float)$str);

      例子:

      $str = "158.2";
      $num = (double)$str;
      print sprintf("%.2f", $num);
      

      编辑:事实上,是的,这是一个精度问题。 (在 C++ 中)通过打印 158.2 到 20 位小数,我得到“158.19999999999998863132”的输出。这是浮点/双精度值的固有问题。在 PHP 中使用echo sprintf("%.20f", $var); 可以看到同样的效果。

      【讨论】:

      • $str="24.299"; $num=(双)$str;打印 sprintf("%.2f",$num);输出 24.30 我需要 24.29
      【解决方案3】:

      首先,PHP 是一种允许您type juggle 的语言。这意味着您不需要 (int)(double) 来做您想做的事情。

      <?php
      $str="158.2"; //could also do $str = 158.2
      echo $str; // Ouput: 158.2
      echo $str * 100; //Output: 15820
      echo number_format($str, 2); //Output: 158.20
      echo number_format(($str*100)/100, 2); //Output: 158.20
      ?>
      

      使用number_format 命令来设置您想要的数字格式。

      更多here

      【讨论】:

      • 由于精度问题,这很棘手。请参阅SO,但它不适用于 158.2
      【解决方案4】:

      切勿将未知分数转换为整数,请参阅http://www.php.net/manual/en/language.types.integer.php 上的手册。 (int) ( (0.1+0.7) * 10 ); 将产生 7,而不是预期的 8。从浮点数转换为整数将始终向下舍入 - 您可能还想检查运算符优先级http://php.net/manual/en/language.operators.precedence.php

      解决方案:在投射之前计算分数。 $fStr = (float) $str; $iStr = (int) $fStr;

      【讨论】:

        【解决方案5】:

        已修复。

            function cutDecimals($number,$decimal){
                $_str=(string)$number;
                if(strpos($_str,".")!==false){
                    $dotPosition=strpos($_str,".")+1;
                    $_numCount=strpos($_str,".");
                    $_decimal=strlen($_str)-$dotPosition;
        
                    if($_decimal<$decimal) return (double)$_str;
                    else return (double)substr($_str,0,$_numCount+$decimal+1);
                }else return (double)$_str;
            }
        
            echo cutDecimals("158.099909865",2)."<br />";
            echo cutDecimals("14.02",2)."<br />";
            echo cutDecimals("41.12566",2)."<br />";
            echo cutDecimals("1.981",2)."<br />";
            echo cutDecimals("0.4111",2)."<br />";
            echo cutDecimals("144.2",2)."<br />";
            echo cutDecimals("55.000000",2)."<br />";
            echo cutDecimals("1456115.499811445121",2)."<br />";
        
        ?>
        

        【讨论】:

          猜你喜欢
          • 2020-06-02
          • 1970-01-01
          • 1970-01-01
          • 2014-06-25
          • 2015-08-07
          • 1970-01-01
          • 2014-03-08
          • 2015-02-23
          • 1970-01-01
          相关资源
          最近更新 更多