Python 代码在将0.0转换为0时工作,但在使用1.0时失败?
Python,3.5版 我有以下代码: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)
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()