【问题标题】:How to round / format long numbers with zeros?如何用零舍入/格式化长数字?
【发布时间】:2018-09-29 14:00:54
【问题描述】:

我有各种长数字,我正在尝试编写一个函数来正确格式化它们。有人可以帮帮我吗?

我已经尝试过“number_format()”和“round()”,但这并不能解决我的问题..

我想像下面这样四舍五入:

1024.43  --> 1,024.43  
0.000000931540 --> 0.000000932  
0.003991 --> 0.00399  
0.3241 --> 0.324
1045.3491 --> 1,045.35

这意味着,如果数字大于“0”,则应四舍五入到小数点后 2 位并添加千位分隔符(如 6,554.24),如果数字小于“1”,则只要数字出现在零之后,则应四舍五入为 3 位(例如 0.0003219 到 0.000322 或 0.2319 到 0.232)

编辑: 这同样适用于“-”值。例如:

-1024.43  --> -1,024.43  
-0.000000931540 --> -0.000000932  
-0.003991 --> -0.00399  
-0.3241 --> -0.324
-1045.3491 --> -1,045.35

【问题讨论】:

  • @MadhurBhaiya 不,因为这个问题是有效数字,这意味着111 变成了110,这是OP 不想要的。 OP 的数字格式似乎是一种非常独特和专业的格式,我无法理解他为什么需要它:)
  • @Davіd 我们可以轻松地使用该函数并在 number > 0 和 number >0 的情况,number_format 就足够了;否则描述的自定义函数
  • 你自己有什么尝试吗?请发帖
  • 我认为这个问题将小于和大于 1 的数字分开,而不是 0。我说的对吗?
  • @MadhurBhaiya 所以你承认这不是完全重复的吗?此外,关于重复的进一步阅读:meta.stackexchange.com/questions/10841/… “如果问题具有相同(潜在)答案,则它们可能是重复的。这不仅包括逐字重复,还包括相同的用不同的语言表达的想法。”

标签: php math numbers format rounding


【解决方案1】:

改编自https://stackoverflow.com/a/48283297/2469308

  • 分两种情况处理。
  • 用于 -1 和 1 之间的数字;我们需要计算要四舍五入的位数。然后,使用number_format() 函数我们可以得到结果。
  • 对于其他情况,只需使用 number_format() 函数并将十进制数字设置为 2。

尝试以下方法:

function customRound($value)
{
   if ($value > -1 && $value < 1) {

       // define the number of significant digits needed
       $digits = 3;

       if ($value >= 0) {

           // calculate the number of decimal places to round to
           $decimalPlaces = $digits - floor(log10($value)) - 1;
       } else {

           $decimalPlaces = $digits - floor(log10($value * -1)) - 1;
       }

       // return the rounded value
       return number_format($value, $decimalPlaces);

   } else {

      // simply use number_format function to show upto 2 decimal places
      return number_format($value, 2);
    } 

    // for the rest of the cases - return the number simply
    return $value;
}

Rextester DEMO

【讨论】:

  • 谢谢。到目前为止,这很棒,而且似乎有效。只有 2 个问题:如果数字太小,它会像这样输出“8.54E-5”,这个脚本也可以处理负数吗?谢谢!
  • @N1njaWTF 检查编辑后的答案。它应该处理非常低的值> 0。它应该如何查找负数?请编辑您的问题以显示负数的示例输出
  • 太棒了!那工作得很好。我已经编辑了我的答案。 :) 如果数字前有“-”,它的格式应该基本相同。谢谢。
  • @N1njaWTF 请检查更新后的答案。我还添加了 rextester 演示。应该对你很好:-)
  • 好人!!完美的作品!我做了一个小编辑,所以它也输出数字“0”:) 非常感谢老兄! rextester.com/PYYT9914
【解决方案2】:
$x = 123.456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
$x = 1.23456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
$x = 0.0123456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
$x = 0.0000123456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
$x = 0.000000123456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
$x = 0.00000000123456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";

输出:

123.45
1.23
0.0123
0.0000123
0.000000123
0.00000000123

基本上,这始终保留最少 2 个十进制数字,最多 3 个有效数字。

但是,由于浮点数在内部处理的方式(作为 2 的幂而不是 10 的幂),存在一些问题。 0.10.001 之类的数字不能精确存储,所以它们实际上存储为0.09999999... 或类似的东西。在这种情况下,它可能看起来像是在计算错误并且给你的答案比它应该的更多。

您可以尝试通过允许公式的误差范围来抵消这种现象:

number_format($x, max(2, 3 - ceil(log10(abs($x))) - 1e-8))

但这可能会导致其他不良影响。您必须进行测试。

【讨论】:

    猜你喜欢
    • 2020-08-20
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 2022-11-02
    • 2018-08-22
    • 2021-12-09
    • 1970-01-01
    • 2011-05-14
    相关资源
    最近更新 更多