Python 代码在将0.0转换为0时工作,但在使用1.0时失败?

Python 代码在将0.0转换为0时工作,但在使用1.0时失败?,python,floating-point,precision,Python,Floating Point,Precision,Python,3.5版 我有以下代码: def drange(start, stop, step): r = start while r < stop: yield r r += step def my_func(): whole_nums = [float(num) for num in range(0, 100)] for x in drange(0.0, 100.01, 0.01): if str(x)

Python,3.5版

我有以下代码:

def drange(start, stop, step):
    r = start
    while r < stop:
        yield r
        r += step

def my_func():
    whole_nums = [float(num) for num in range(0, 100)]
    for x in drange(0.0, 100.01, 0.01):
        if str(x).split('.')[1] == '0':
            x = str(x).split('.')[0]
        else:
            x = round(x, 2)
        print(str(x))
        time.sleep(0.2)
def排放(启动、停止、步骤):
r=开始
当r
drange
函数循环给定的数字,以给定的增量生成数字。问题是我想要0、1、2、3等等,但它会产生0.0、1.0等等

我想,既然我知道这些错误数字的格式(所有其他介于0.01和99.99之间的数字),我就可以:

str(编号).split('.')[1]

(如
my_func
)中所示,如果输出是
'0'
,那么我就知道我有一个0.0、1.0等,并且可以使用
str(the number.split('.)[0]
获取我想要的输出,当然还可以将其转换为int或其他形式

但是!当我执行
my_func
时,
.split()
解决方案只在0.0上工作,当它达到1.0时,它只跳过
if
语句并进入
else
,打印出1.0而不是1

代码在不导入任何内容的情况下应该可以正常运行,所以可以随意尝试一下

更新 好吧,看来我的方法根本上是有缺陷的(见@danils-answer),所以我现在的问题是:如何生成0到100之间的数字,以0.01为增量,同时确保整数是整数。所以


0,0.01,…,1,1.01,1.1,1.02。。。99.5,99.51,…,100

这是因为浮点运算。它不完全是
1.0
你得到的,更像
1.0000000000000007
。所以
str(x).split('.')[1]='0000000000000007'

> import numpy as np
> np.arange(0.0, 100.0, 0.1)
array([   0. ,    0.1,    0.2, ...,   99.8,   99.9,  100. ])

千万不要依赖浮点整数的字符串表示法,因为它们很少有精确的表示法(近似值会导致精度不准确,这会给工作带来麻烦)

您不需要
str(x)
print
,因为
print
会自动为您执行此操作

此外,在步骤中生成下一个值时,
drange
函数似乎会引入浮点不准确。您可以使用
np.arange
作为范围,它支持小数步:

import numpy as np
out = np.arange(0.0, 100.01, 0.01)
print(out)

array([  0.00000000e+00,   1.00000000e-02,   2.00000000e-02, ...,
         9.99800000e+01,   9.99900000e+01,   1.00000000e+02])
注意:如果您没有
numpy
,可以使用
pip install numpy
安装它

最后,您可以使用
float.is_integer
检查浮点是否为整数


这将为您提供:

0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
...

对于不涉及numpy的版本:

import time

def drange(start, stop, step):
    r = start
    while r < stop:
        yield r
        r += step

def my_func():
    whole_nums = [float(num) for num in range(0, 100)]
    for x in drange(0.0, 100.01, 0.01):
        x = float(int(x * 100))/100
        if x.is_integer():
            print(int(x))
        else:
            print (x)
        time.sleep(0.01)

if __name__ == "__main__":
    my_func()
导入时间
def排放(启动、停止、步骤):
r=开始
当r

不可否认,截断函数很复杂。

为什么不简单地比较
round(x)
int(x)
看看它是否是一个整数?或者更好的方法是使用
float.is_integer
。也可以,这对我的方法来说似乎有问题。我假设执行int('00000000000000 7')最多只能产生一个'7'。我实现了您的解决方案,但不幸的是,我得到了相同类型的错误行为。很可能是因为@Danil Speransky的回答。你能试着运行一下你的例子,看看你是否也得到了1.0而不是预期的1吗?@7013145问题是由于你的
drange
函数在加法过程中引入了不精确性。我用
np.arange
做了同样的尝试,效果非常好。@7013145如果你有numpy,你可以用我的答案。行得通。噢,斯纳普兄弟,你的编辑真是妙极了!感谢您澄清我的错误行为,以及一个如此容易实施的有效解决方案。Numpy真的是一个强大的模块,我开始意识到。是的,但你的解决方案仍然有效:)我会选择Numpy解决方案,尽管我对循环中是否存在任何性能差异感兴趣。
import time

def drange(start, stop, step):
    r = start
    while r < stop:
        yield r
        r += step

def my_func():
    whole_nums = [float(num) for num in range(0, 100)]
    for x in drange(0.0, 100.01, 0.01):
        x = float(int(x * 100))/100
        if x.is_integer():
            print(int(x))
        else:
            print (x)
        time.sleep(0.01)

if __name__ == "__main__":
    my_func()