【问题标题】:No Truncate function in PHP - Options?PHP 中没有截断函数 - 选项?
【发布时间】:2012-05-17 20:46:58
【问题描述】:

我有一个执行以下计算的算法:

  1. ( ( 0.50 * 0 ) + 7 ) / 10 = 0.70
  2. ( ( 0.70 * 10 ) + 9 ) / 20 = 0.80
  3. ( ( 0.80 * 20 ) + 7 ) / 30 = 0.7666666667 -> 我希望将此值截断为 0.76

这样它就可以输入到其余的计算中:

4a。 ( ( 0.76 * 30 ) + 8 ) / 40 = 0.77

并且在将小数点后两位四舍五入为0.77时输入:

4b。 ( ( 0.77 * 30 ) + 8 ) / 40 = 0.77

****以下似乎失败了,而是强制向上取整到 0.77:****

PHP sptrinf() 函数:PHP dropping decimals without rounding up

PHP number_format() 函数:PHP: show a number to 2 decimal places

PHP floor() 函数:Truncate float numbers with PHP

  • 还有其他方法吗?
  • 是否有可能使用 PHP 实现我想要的(截断到小数点后两位)?

请帮忙。非常感谢。

更新 - 已解决 好的,多亏了 dkamins 和 zneak,它现在可以工作了。我使用了 floor() 方法(我假设我过去没有做正确的事情)。 但是,现在发生了以下情况:

例如

(0.86 * 30) + 9 ) / 40 = 0.87(应该),但在 TRUNC 之后它 = 0.86

如何将 0.87 截断为 0.86?这没有道理。有没有办法让它仅在小数点超过 2 位时截断?

已解决:

$numDecPlace = strlen(substr(strrchr($newRel, "."), 1));
echo '<p>Test: Number of decimal places=' .$numDecPlace. '</p>';
if($numDecPlace > 2) {
    $newRel = floor($newRel * 100) / 100; // Truncate to 2dp.
    echo '<p>Test: New relationship truncated is $newRel=' .$newRel. '</p>';
}

【问题讨论】:

  • 您应该查看@Fernando Prieto his answer below。他使用基于(子)字符串的方法,类似于您选择的解决方案的第一部分,但我个人认为它可能更有效、更健壮。

标签: php decimal truncate floor


【解决方案1】:

这里给出的所有答案都围绕数字。 这个功能对我有用,我也希望对你有用。

function truncate($number, $decimals)
{
  $point_index = strrpos($number, '.'); 
  return substr($number, 0, $point_index + $decimals+ 1);
}

其中$number 是要截断的数字,$decimals 是您想要的小数位数。 示例: truncate(-38.59540719940386 , 6); 返回 -38.595407

如果需要,请查看substr 的文档!

【讨论】:

  • 我喜欢这个功能有多种原因:它很清晰,很容易理解它的工作原理,没有难以理解的魔法发生。此外,它非常高效,你知道 100% 肯定不会出现奇怪的舍入错误。
  • 这个函数不能正确处理指数形式的浮点数(例如“2.5E7”)。此外,对于非常小的负浮点数,它会返回像“-0.0000000”这样的字符串。
【解决方案2】:

您可以使用 PHP 的 floor 函数以及一些小数移位,如下所示:

floor(0.7666666667 * 100) / 100;

【讨论】:

  • 如果你觉得它难看,你可以在它周围做一个薄包装:function trunc($number, $places) { $power = pow(10, $places); return floor($number * $power) / $power; }
  • 好吧,这太多了。它现在似乎正在工作(典型)。我已经使用了标准楼层(num * 100)/100 和函数(感谢 zneak),两者都很好,我得到了 0.76。非常感谢。然而,我有一个后续行动,见上 :)
【解决方案3】:

round()怎么样

  <?php
  echo round(3.4);         // 3
  echo round(3.5);         // 4
  echo round(3.6);         // 4
  echo round(3.6, 0);      // 4
  echo round(1.95583, 2);  // 1.96
  echo round(1241757, -3); // 1242000
  echo round(5.045, 2);    // 5.05
  echo round(5.055, 2);    // 5.06
  ?>

【讨论】:

    【解决方案4】:

    要对 +ve -ve 数字准确地执行此操作,您需要使用:
    - +ve 数字的 php floor() 函数
    - -ve 数字的 php ceil() 函数

    function truncate_float($number, $decimals) {
        $power = pow(10, $decimals); 
        if($number > 0){
            return floor($number * $power) / $power; 
        } else {
            return ceil($number * $power) / $power; 
        }
    }
    

    原因是floor() 总是将数字向下四舍五入,而不是向零。
    floor() 有效地将 -ve 数字舍入朝向更大的绝对值
    例如floor(1.5) = 1floor(-1.5) = 2

    因此对于使用multiply by power, round, then divide by power的截断方法:
    - floor() 仅适用于正数
    - ceil() 仅适用于负数

    要对此进行测试,请将以下代码复制到http://phpfiddle.org/lite(或类似)的编辑器中:

    <div>Php Truncate Function</div>
    <br>
    <?php
        function truncate_float($number, $places) {
            $power = pow(10, $places); 
            if($number > 0){
                return floor($number * $power) / $power; 
            } else {
                return ceil($number * $power) / $power; 
            }
        }
    
        // demo
        $lat = 52.4884;
        $lng = -1.88651;
        $lat_tr = truncate_float($lat, 3);
        $lng_tr = truncate_float($lng, 3);
        echo 'lat = ' . $lat . '<br>';
        echo 'lat truncated = ' . $lat_tr . '<br>';
        echo 'lat = ' . $lng . '<br>';
        echo 'lat truncated = ' . $lng_tr . '<br><br>';
    
        // demo of floor() on negatives
        echo 'floor (1.5) = ' . floor(1.5) . '<br>';
        echo 'floor (-1.5) = ' . floor(-1.5) . '<br>';
    ?>
    

    【讨论】:

      【解决方案5】:

      我使用过 Kartikey 提到的 round() 函数。你可以在这里找到更多信息PHP.Net

      float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] )
      

      【讨论】:

      • 好像没有“趋于零”的模式,所以不能用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-05
      • 2019-12-19
      • 2019-04-30
      • 2021-12-04
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      相关资源
      最近更新 更多