Ale*_*lex 8 python arrays numpy
总之,我遇到的问题是这样的:
aa = np.arange(-1., 0.001, 0.01)
aa[-1]
Out[16]: 8.8817841970012523e-16
Run Code Online (Sandbox Code Playgroud)
实际上,这会导致一系列问题,因为我的模拟不允许正值输入。
我可以通过以下方式解决:
aa = np.arange(-100, 1, 1)/100.
aa[-1]
Out[21]: 0.0
Run Code Online (Sandbox Code Playgroud)
但这是一种痛苦。实际上,您不能每次都这样做。
这似乎是一个如此基本的问题。这里一定有我遗漏的东西。顺便说一下,我使用的是 Python 2.7.13。
发生这种情况是因为 Python(像大多数现代编程语言一样)使用浮点运算,它不能准确地表示某些数字(请参阅浮点运算是否被破坏?)。
这意味着,无论您使用的是 Python 2、Python 3、R、C、Java 等,您都必须考虑将两个浮点数相加的效果。
np.arange通过重复将step值添加到值来工作start,这最终会导致不精确:
>>> start = -1
>>> for i in range(1000):
... start += 0.001
>>> start
8.81239525796218e-16
Run Code Online (Sandbox Code Playgroud)
相似地:
>>> x = np.arange(-1., 0.001, 0.01)
>>> x[-1]
8.8817841970012523e-16
Run Code Online (Sandbox Code Playgroud)
用于规避此问题的典型模式是在需要重复操作时尽可能使用整数。所以,例如,我会做这样的事情:
>>> x = 0.01 * np.arange(-100, 0.1)
>>> x[-1]
0.0
Run Code Online (Sandbox Code Playgroud)
或者,您可以创建一个单行便利函数来为您执行此操作:
>>> def safe_arange(start, stop, step):
... return step * np.arange(start / step, stop / step)
>>> x = safe_arange(-1, 0.001, 0.01)
>>> x[-1]
0
Run Code Online (Sandbox Code Playgroud)
但请注意,即使这样也无法绕过浮点精度的限制;例如,数字 -0.99不能用浮点精确表示:
>>> val = -0.99
>>> print('{0:.20f}'.format(val))
-0.98999999999999999112
Run Code Online (Sandbox Code Playgroud)
因此,在使用任何语言处理浮点数时,您必须始终牢记这一点。