【问题标题】:For loop increasement by 3rd decimal point phpFor循环递增第3个小数点php
【发布时间】:2023-04-05 10:48:01
【问题描述】:

我需要一个循环来将数字增加小数点后第三位,打印应该是这样的

1.1
1.101
1.102
1.103
...
2.0
2.001
2.002
...
2.1
2.101
...

for ($i = 1.1; $i <= 3; $i += .001){

   echo $i . '<br />';
}

开始似乎没问题 但是在循环的某个地方,十进制数变得很大

1.54
1.541
1.542
1.543
1.544
1.545
1.546
1.547
1.548
1.549
1.55
1.551
1.552
1.553
1.554
1.5549999999999
1.5559999999999
1.5569999999999
1.5579999999999
1.5589999999999

如果我使用

number_format($i,3)

我所有的数字都有 3 个小数点,例如

1.100,我需要它是 1.1。

我错过了什么?

【问题讨论】:

  • 这与PHP中浮点数的存储方式有关link
  • @MatejŽvan 这个问题不是 php 特有的,它是浮点运算的一般效果。

标签: php for-loop


【解决方案1】:

这是浮点运算工作方式的影响。这可能导致精度差。问题是计算中的错误加起来了。所以一般来说,单独四舍五入并不是很安全。它的安全性取决于添加的次数,所以这里的迭代次数...

试试这样吧:

for ($i = 1100; $i <= 3000; $i++) {
   echo $i/1000 . "<br>\n";
}

上面使用整数计算代替,以下除法不会导致累加错误。

【讨论】:

  • @button 当然可以,试一试。为什么不应该呢?
  • 它实际上是正确的,但我不明白为什么在这种情况下回合会有所不同?可以合作吗?
  • 如前所述:错误随着迭代而增加(好吧,这很简单,但仍然正确)。只是将输出四舍五入是不安全的。可行的方法是将总和四舍五入,例如for ($i = 1.1; $i &lt;= 3; $i = round($i+.001,3))。因为每次迭代的最大误差保证低于迭代。但这会慢得多......上面的更容易更快。
  • @Benn 抱歉,忘记联系您了。见上文:^^^
  • 现在明白了,但对于我的使用(我将它用于 em 行高),圆形似乎还可以并且足够精确。如果这是更大的迭代,我会选择你的解决方案。谢谢你的信息
【解决方案2】:

Live demo

尝试将值四舍五入并将它们存储在 $i 中:

for ($i = 1.1; $i <= 3; $i += .001){
    $i = round($i, 3);
   echo $i . '<br />';
}

【讨论】:

    【解决方案3】:

    阅读浮点数。基本上,并不是所有的十进制数都可以用浮点数精确表示。

    尝试四舍五入:

    for ($i = 1.1; $i <= 3; $i += .001){
       echo round($i,3) . '<br />';
    }
    

    【讨论】:

      【解决方案4】:

      这应该适合你:

      (这里我只是使用sprintf() 并指定它应该显示一个双精度(lf -> long float)到小数点后第三位)

      echo sprintf("%.3lf", $i) . '<br />';
      

      如果您想知道为什么会得到此结果,请参阅:Is floating point math broken?

      顺便说一句:这个方法也有副作用,它显示:1.560 而不是1.56

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-04
        • 1970-01-01
        • 2017-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-17
        相关资源
        最近更新 更多