【问题标题】:Remove useless zero digits from decimals in PHP从 PHP 中的小数中删除无用的零位
【发布时间】:2013-01-09 23:59:31
【问题描述】:

我正在尝试找到一种快速的方法来从数值中删除zero decimals,如下所示:

echo cleanNumber('125.00');
// 125

echo cleanNumber('966.70');
// 966.7

echo cleanNumber(844.011);
// 844.011

是否存在一些优化的方法来做到这一点?

【问题讨论】:

  • 由于您的值实际上是字符串,为什么不简单地使用 rtrim() - php.net/manual/en/function.rtrim.php - 带有“0”。作为第二个参数
  • 对不起,我还不是很清楚,它们并不总是字符串,我解决了这个问题。
  • @Mark Ba​​ker:这是一个不好的方法,因为数字 120 将被修剪为 12
  • @machineaddict - 当且仅当字符串值没有小数点时才会出现...... OP 引用的所有值都有小数点。
  • 那么你应该在你的答案中添加一个粗体通知,它只有在有小数的情况下才有效。

标签: php numbers decimal


【解决方案1】:

示例 1

$value =81,500.00;
{{rtrim(rtrim(number_format($value,2),0),'.')}}

输出

81,500

示例 2

$value=110,763.14;
{{rtrim(rtrim(number_format($value,2),0),'.')}}

输出

110,763.14

【讨论】:

  • 纯代码答案并不是特别有用。请添加一些关于此代码如何解决问题的描述。
【解决方案2】:

我使用这个简单的代码:

define('DECIMAL_SEPARATOR', ','); //To prove that it works with different separators than "."

$input = "50,00";

$number = rtrim($input, '0');                // 50,00 --> 50,
$number = rtrim($number, DECIMAL_SEPARATOR); // 50,   --> 50

echo $number;

似乎有点太容易成为真正正确的解决方案,但它对我来说效果很好。在使用它之前,您应该对将获得的输入进行一些测试。

【讨论】:

    【解决方案3】:

    您可以尝试以下方法:

    rtrim(number_format($coin->current_price,6),'0.')
    

    【讨论】:

      【解决方案4】:

      下面的就简单多了

      if(floor($num) == $num) {
          echo number_format($num);
      } else {
          echo $num;
      }
      

      【讨论】:

        【解决方案5】:

        终极解决方案:唯一安全的方法是使用正则表达式:

        echo preg_replace("/\.?0+$/", "", 3.0); // 3
        echo preg_replace("/\d+\.?\d*(\.?0+)/", "", 3.0); // 3
        

        它适用于任何情况

        【讨论】:

          【解决方案6】:

          只需将 + 添加到您的字符串变量中,就会导致类型转换为 (float) 并删除零:

          var_dump(+'125.00');     // double(125)
          var_dump(+'966.70');     // double(966.7)
          var_dump(+'844.011');    // double(844.011)
          var_dump(+'844.011asdf');// double(844.011)
          

          【讨论】:

            【解决方案7】:

            简单而准确!

            function cleanNumber($num){
                $explode = explode('.', $num);
                $count   = strlen(rtrim($explode[1],'0'));
                return bcmul("$num",'1', $count);
            }
            

            【讨论】:

              【解决方案8】:

              对于来到这个网站的每个人都遇到同样的逗号问题,请更改:

              $num = number_format($value, 1, ',', '');
              

              到:

              $num = str_replace(',0', '', number_format($value, 1, ',', '')); // e.g. 100,0 becomes 100
              


              如果有两个零要删除,则改为:

              $num = str_replace(',00', '', number_format($value, 2, ',', '')); // e.g. 100,00 becomes 100
              

              更多:PHP number: decimal point visible only if needed

              【讨论】:

                【解决方案9】:

                我发现这个解决方案是最好的:

                public function priceFormat(float $price): string
                {
                    //https://stackoverflow.com/a/14531760/5884988
                    $price = $price + 0;
                    $split = explode('.', $price);
                    return number_format($price, isset($split[1]) ? strlen($split[1]) : 2, ',', '.');
                }
                

                【讨论】:

                  【解决方案10】:

                  这是一个简单的使用 rtrim 的单行函数,保存分隔符和小数点:

                  function myFormat($num,$dec)
                   {
                   return rtrim(rtrim(number_format($num,$dec),'0'),'.');
                   }
                  

                  【讨论】:

                    【解决方案11】:

                    这是我的解决方案。 我想保留添加千位分隔符的能力

                        $precision = 5;    
                        $number = round($number, $precision);
                        $decimals = strlen(substr(strrchr($number, '.'), 1));
                        return number_format($number, $precision, '.', ',');
                    

                    【讨论】:

                      【解决方案12】:

                      如果您想删除之前的零位以显示在页面或模板上。

                      你可以使用sprintf()函数

                      sprintf('%g','125.00');
                      //125
                      
                      ‌‌sprintf('%g','966.70');
                      //966.7
                      
                      ‌‌‌‌sprintf('%g',844.011);
                      //844.011
                      

                      【讨论】:

                      • 谢谢我喜欢这个答案。这对我很有帮助。
                      • 小数分隔符和千位分隔符怎么改?
                      • @RayCoder sprintf 没有添加千位分隔符的选项,您可以尝试:sprintf('%s', number_format(2699, 0, '.', ','))
                      【解决方案13】:

                      添加 +0 时要小心。

                      echo number_format(1500.00, 2,".",",")+0;
                      //1
                      

                      这个结果是 1。

                      echo floatval('1,000.00');
                      // 1
                      
                      echo floatval('1000.00');
                      //1000
                      

                      【讨论】:

                      • 您正在回答 2013 年的问题。
                      • 回答一个老问题没问题,如果它可以帮助实际的读者
                      【解决方案14】:

                      这是我的小解决方案... 可以包含到一个类中并设置变量

                      私人 $dsepparator = '.'; // 小数点 私人 $tsepparator= ','; // 千

                      可以由构造函数设置并更改为用户语言。

                      class foo
                      {
                          private $dsepparator;
                          private $tsepparator;
                      
                          function __construct(){
                              $langDatas = ['en' => ['dsepparator' => '.', 'tsepparator' => ','], 'de' => ['dsepparator' => ',', 'tsepparator' => '.']];
                              $usersLang = 'de'; // set iso code of lang from user
                              $this->dsepparator = $langDatas[$usersLang]['dsepparator'];
                              $this->tsepparator = $langDatas[$usersLang]['tsepparator'];
                          }
                      
                          public function numberOmat($amount, $decimals = 2, $hideByZero = false)
                          {
                              return ( $hideByZero === true AND ($amount-floor($amount)) <= 0 ) ? number_format($amount, 0, $this->dsepparator, $this->tsepparator) : number_format($amount, $decimals, $this->dsepparator, $this->tsepparator);
                          }
                          /*
                           * $bar = new foo();
                           * $bar->numberOmat('5.1234', 2, true); // returns: 5,12
                           * $bar->numberOmat('5', 2); // returns: 5,00
                           * $bar->numberOmat('5.00', 2, true); // returns: 5
                           */
                      
                      }
                      

                      【讨论】:

                      • 所以我用很少的样本构建了一个样本类。更好的? =)
                      【解决方案15】:

                      由于这个问题是旧的。首先,我很抱歉。

                      问题是关于数字 xxx.xx,但如果它是 x,xxx.xxxxx 或差异小数分隔符,例如 xxxx,xxxx,这可能更难找到并从十进制值中删除零位。

                      /**
                       * Remove zero digits from decimal value.
                       * 
                       * @param string|int|float $number The number can be any format, any where use in the world such as 123, 1,234.56, 1234.56789, 12.345,67, -98,765.43
                       * @param string The decimal separator. You have to set this parameter to exactly what it is. For example: in Europe it is mostly use "," instead of ".".
                       * @return string Return removed zero digits from decimal value.
                       */
                      function removeZeroDigitsFromDecimal($number, $decimal_sep = '.')
                      {
                          $explode_num = explode($decimal_sep, $number);
                          if (is_array($explode_num) && isset($explode_num[count($explode_num)-1]) && intval($explode_num[count($explode_num)-1]) === 0) {
                              unset($explode_num[count($explode_num)-1]);
                              $number = implode($decimal_sep, $explode_num);
                          }
                          unset($explode_num);
                          return (string) $number;
                      }
                      

                      这是测试代码。

                      $numbers = [
                          1234,// 1234
                          -1234,// -1234
                          '12,345.67890',// 12,345.67890
                          '-12,345,678.901234',// -12,345,678.901234
                          '12345.000000',// 12345
                          '-12345.000000',// -12345
                          '12,345.000000',// 12,345
                          '-12,345.000000000',// -12,345
                      ];
                      foreach ($numbers as $number) {
                          var_dump(removeZeroDigitsFromDecimal($number));
                      }
                      
                      
                      echo '<hr>'."\n\n\n";
                      
                      
                      $numbers = [
                          1234,// 12324
                          -1234,// -1234
                          '12.345,67890',// 12.345,67890
                          '-12.345.678,901234',// -12.345.678,901234
                          '12345,000000',// 12345
                          '-12345,000000',// -12345
                          '12.345,000000',// 12.345
                          '-12.345,000000000',// -12.345
                          '-12.345,000000,000',// -12.345,000000 STRANGE!! but also work.
                      ];
                      foreach ($numbers as $number) {
                          var_dump(removeZeroDigitsFromDecimal($number, ','));
                      }
                      

                      【讨论】:

                        【解决方案16】:
                        $str = 15.00;
                        $str2 = 14.70;
                        echo rtrim(rtrim(strval($str), "0"), "."); //15
                        echo rtrim(rtrim(strval($str2), "0"), "."); //14.7
                        

                        【讨论】:

                          【解决方案17】:

                          你可以使用:

                          print (floatval)(number_format( $Value), 2 ) );    
                          

                          【讨论】:

                            【解决方案18】:
                            $value = preg_replace('~\.0+$~','',$value);
                            

                            【讨论】:

                            • 如果您解释了您的代码的作用以及它将如何解决原始问题,这将提高您的答案质量。
                            • @Nikhil Gyan 我同意这个答案不是很好。随意 ote 下来。但是,我至少认为对于质量非常低的标志来说还不够糟糕
                            【解决方案19】:

                            此代码将删除点后的零,并且只返回两位小数。

                            $number=1200.0000;
                            str_replace('.00', '',number_format($number, 2, '.', ''));

                            输出将为:1200

                            【讨论】:

                              【解决方案20】:

                              类型转换为float。

                              $int = 4.324000;
                              $int = (float) $int;
                              

                              【讨论】:

                                【解决方案21】:
                                $x = '100.10'; 
                                $x = preg_replace("/\.?0*$/",'',$x); 
                                echo $x;
                                

                                没有什么是不能用简单的正则表达式解决的;)

                                http://xkcd.com/208/

                                【讨论】:

                                • 删除重要的0s,例如"100"。也无法将0s 剥离"100.010"。
                                • 大家退后! $x = preg_replace("/(\.0*$)|((?&lt;=\.\d*)0+$)/",'',$x);
                                【解决方案22】:

                                这是我用的:

                                function TrimTrailingZeroes($nbr) {
                                    return strpos($nbr,'.')!==false ? rtrim(rtrim($nbr,'0'),'.') : $nbr;
                                }
                                

                                注意这假设 . 是小数点分隔符。它的优点是它可以处理任意大(或小)的数字,因为没有浮点数。它也不会将数字转换为科学计数法(例如 1.0E-17)。

                                【讨论】:

                                • 这不是一个安全的解决方案,如果价格不是十进制怎么办?例如,如果开发人员将价格乘以一个整数,那么我们就有一个整数
                                • @alex 这个函数适用于整数、浮点数和字符串。
                                • bcmath 的完美解决方案
                                • 如果输入可能包含逗号千位分隔符(无法转换为浮点数),这是唯一有效的答案。如果输入来自number_format(),如果提供十进制值,则始终包含小数分隔符,则代码可以简化为,例如:$output = rtrim(rtrim(number_format($input, 10), '0'), '.')
                                • 在执行number_format() 之后解析结果效果很好。谢谢!
                                【解决方案23】:

                                $num + 0 可以解决问题。

                                echo 125.00 + 0; // 125
                                echo '125.00' + 0; // 125
                                echo 966.70 + 0; // 966.7
                                

                                在内部,这相当于使用 (float)$num 或 floatval($num) 强制转换为浮动,但我发现它更简单。

                                【讨论】:

                                • 我认为这是一个肮脏的把戏。我不喜欢它,因为代码没有告诉他像floatval() 这样的行为。
                                • @ESCOBAR floatval 的行为是返回一个浮点数。我认为将其用作小数格式化程序也不是很明显或干净。
                                • 这个很不清楚。我们团队刚刚在我们的代码中遇到了这个问题,这让 3 位开发人员困惑了一段时间。我认为Mark's answer 是一个更好的选择。它更长,但它的意图很明确。
                                • @jfbalanc //COMMENT
                                • @ESCOBAR 不是,这是官方推荐的类型转换方法...在 php.net 上搜索“type juggling”
                                【解决方案24】:

                                方法复杂但有效:

                                $num = '125.0100';
                                $index = $num[strlen($num)-1];
                                $i = strlen($num)-1;
                                while($index == '0') {
                                   if ($num[$i] == '0') {
                                     $num[$i] = '';
                                     $i--;
                                   }
                                
                                   $index = $num[$i];
                                }
                                
                                //remove dot if no numbers exist after dot
                                $explode = explode('.', $num);
                                if (isset($explode[1]) && intval($explode[1]) <= 0) {
                                   $num = intval($explode[0]);
                                }
                                
                                echo $num; //125.01
                                

                                上述解决方案是最佳方式,但如果您想拥有自己的解决方案,您可以使用它。该算法的作用是从字符串的末尾开始并检查其是否为 0,如果是则设置为空字符串,然后从后面转到下一个字符,直到最后一个字符为 > 0

                                【讨论】:

                                  【解决方案25】:

                                  您应该将您的数字转换为浮点数,这将为您完成。

                                  $string = "42.422005000000000000000000000000";
                                  echo (float)$string;
                                  

                                  这将是您正在寻找的输出。

                                  42.422005

                                  【讨论】:

                                  • 浮动转换也可能会损坏您的号码。例如(float)'0.1234567890124567890123456789' 变为 0.12345678901246。
                                  【解决方案26】:

                                  你可以使用floatval函数

                                  echo floatval('125.00');
                                  // 125
                                  
                                  echo floatval('966.70');
                                  // 966.7
                                  
                                  echo floatval('844.011');
                                  // 844.011
                                  

                                  【讨论】:

                                  • 千位分隔符为点,小数点为逗号时失败。
                                  猜你喜欢
                                  • 2021-01-22
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2018-02-15
                                  • 1970-01-01
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多