Perl循环去干扰 [英] Perl for loop going haywire

查看:121
本文介绍了Perl循环去干扰的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Perl中有一个简单的循环

  for($ i = 0; $ i <= 360; $ i + = 0.01)
{
print$ i;

$ / code>

为什么当我运行这段代码时,我得到了如下的输出:一旦达到0.81,它会突然开始加载更多的小数位?我知道我可以简单地围绕避免这个问题,但我想知道为什么会发生。 0.01的增量似乎并不疯狂。

  0.77 
0.78
0.79
0.8
0.81
0.820000000000001
0.830000000000001
0.840000000000001
0.850000000000001
0.860000000000001
0.870000000000001


解决方案

计算机使用二进制表示法。并不是所有的十进制浮点数都有二进制表示法的精确表示,所以可能会发生一些错误(实际上是一个舍入差异)。这也是为什么你不应该使用浮点数作为货币值: / p>

搞砸了recepit http:// img。 thedailywtf.com/images/200902/errord/DSC00669.JPG

(图片来自 dailywtf



最好的解决方法是使用整数进行计算,将它们除以正确的小数位数,然后使用 sprintf 来限制打印的小数位数。这将确保:


  • 总是要打印结果






  •  <$ c 
  • ($ i = 0; $ i <= 360 * 100; $ i + = 1)
    printf%.2f \ n$ c>#!/ usr / bin / perl
    ,$ i / 100;
    }


    I have a simple for loop in Perl

    for ($i=0; $i <= 360; $i += 0.01)
    {
    print "$i ";
    }
    

    Why is it that when I run this code I get the following output, where as soon as it gets to 0.81 it suddenly starts to add in a load more decimal places? I know I could simply round up to avoid this issue but I was wondering why it happens. An increment of 0.01 does not seem at all crazy to do.

     0.77
     0.78
     0.79
     0.8
     0.81
     0.820000000000001
     0.830000000000001
     0.840000000000001
     0.850000000000001
     0.860000000000001
     0.870000000000001
    

    解决方案

    Computers use binary representations. Not all decimal floating point numbers have exact representations in binary notation, so some error can occur (its actually a rounding difference). This is the same reason why you shouldn't use floating point numbers for monetary values:

    messed up recepit http://img.thedailywtf.com/images/200902/errord/DSC00669.JPG

    (Picture taken from dailywtf)

    Most elegant way to get around this issue is using integers for calculations, dividing them to the correct number of decimal places and using sprintf to limit the number of decimal places printed. This will both make sure:

    • There's always to correct result printed
    • The rounding error doesn't accumulate

    Try this code:

    #!/usr/bin/perl
    for ($i=0; $i <= 360*100; $i += 1) {
      printf "%.2f \n", $i/100;
    }
    

    这篇关于Perl循环去干扰的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆