【问题标题】:looping float range循环浮动范围
【发布时间】:2012-08-13 05:23:13
【问题描述】:

你能帮我解决这个问题吗?

代码:-

import numpy as np

def test(numList):
    yesList=[]
    for num in numList:
        print num, "start here"
        for i in np.arange(2.0,3.0,0.1):
            print i
        if num==i: yesList.append(num)
    return yesList

print test([2.1,2.3,3.0])

输出:-

2.1 start here
2.0
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
2.3 start here
2.0
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
3.0 start here
2.0
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
[2.1]

我希望它打印[2.1,2.3],但它只给我[2.1],如图所示。

【问题讨论】:

  • 您似乎已经在标签中发现了问题 - 浮点数。
  • 您的格式最初不正确(该函数无法编译),因此我不得不根据您的示例输出猜测您的意思。如果我猜错了,请更正。

标签: python numpy floating-point


【解决方案1】:

简短的回答是,您使用的是浮点(不精确)数字并期望得到精确的结果,这最终会失败。长答案要复杂得多,但首先看一下this site's floating-point FAQ 中的第一项:Is floating point math broken?(这是一个 JavaScript 问题,但它同样适用于所有语言。)

【讨论】:

    【解决方案2】:

    这还取决于循环变量如何在 python 中递增... (i+1)-th 循环值可以是任一

      value[i] = startValue + i * increment
    

      value[i] = value[i-1] + increment
    

    在浮点数中,这些值会有所不同...
    所以如果你想处理严格的浮点相等,你必须知道这种细节

    此外,很难控制循环何时停止...最后一个值很可能是 (3.0-epsilon)

    第一条规则是不要在浮点上使用循环,无论是什么语言
    改用整数:

    def test(numList):
        yesList=[]
        for num in numList:
            print num, "start here"
            for i in np.arange(20,30,1):
                print i*0.1
                if num==(i/10.0): yesList.append(num)
        return yesList
    

    还要注意 i*0.1 和 i/10.0 可能不同,因为浮点数 0.1 不完全是 1/10...
    所以,如果你写 if num==(i*0.1) 它不会像你期望的那样工作......
    例如 (23*0.1) == (23/10.0) 是假的,虽然最后一个恰好严格等于浮点数 2.3,但它们都不同于数学分数 23/10。

    第二条规则告诉不要在浮点数上使用严格相等,这很少是你想的

    def test(numList):
        yesList=[]
        for num in numList:
            print num, "start here"
            for i in np.arange(20,30,1):
                print i*0.1
                if abs(num-0.1*i) < 0.05 : yesList.append(num)
        return yesList
    

    请阅读“每位计算机科学家应了解的浮点运算知识”。 http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

    【讨论】:

      猜你喜欢
      • 2020-11-15
      • 1970-01-01
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 2018-05-07
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      相关资源
      最近更新 更多