numpy arange:如何制作“精确"浮点数数组? [英] numpy arange: how to make "precise" array of floats?

查看:32
本文介绍了numpy arange:如何制作“精确"浮点数数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总之,我遇到的问题是这样的:

aa = np.arange(-1., 0.001, 0.01)aa[-1]出[16]:8.8817841970012523e-16

实际上,这会导致一系列问题,因为我的模拟不允许正值输入.

我可以通过以下方式绕过:

aa = np.arange(-100, 1, 1)/100.aa[-1]出[21]:0.0

但这很痛苦.实际上,您不可能每次都这样做.

这似乎是一个很基本的问题.这里一定有我遗漏的东西.顺便说一下,我使用的是 Python 2.7.13.

解决方案

发生这种情况是因为 Python(与大多数现代编程语言一样)使用浮点运算,无法准确表示某些数字(请参阅 浮点数学被破坏了吗?).

这意味着,无论您使用的是 Python 2、Python 3、R、C、Java 等,您都必须考虑将两个浮点数相加的效果.

np.arange 通过将 step 值重复添加到 start 值来工作,这最终导致不精确:<预><代码>>>>开始 = -1>>>对于我在范围内(1000):... 开始 += 0.001>>>开始8.81239525796218e-16

同样:

<预><代码>>>>x = np.arange(-1., 0.001, 0.01)>>>x[-1]8.8817841970012523e-16

用于规避此问题的典型模式是在需要重复操作时尽可能使用整数.所以,例如,我会做这样的事情:

<预><代码>>>>x = 0.01 * np.arange(-100, 0.1)>>>x[-1]0.0

或者,您可以创建一个方便的单行函数来为您执行此操作:

<预><代码>>>>def safe_arange(开始,停止,步骤):... return step * np.arange(start/step, stop/step)>>>x = safe_arange(-1, 0.001, 0.01)>>>x[-1]0

但请注意,即使这样也无法绕过浮点精度的限制;例如,数字 -0.99 不能用浮点数精确表示:

<预><代码>>>>价值 = -0.99>>>打印('{0:.20f}'.format(val))-0.98999999999999999112

因此,在使用任何语言处理浮点数时,您必须始终牢记这一点.

In short, the problem I encounter is this:

aa = np.arange(-1., 0.001, 0.01)
aa[-1]
Out[16]: 8.8817841970012523e-16

In reality, this cause a series problem since my simulations doesn't allow positive value inputs.

I can sort of get around by doing:

aa = np.arange(-100, 1, 1)/100.
aa[-1]
Out[21]: 0.0

But this is a pain. Practically you can't do this every time.

This seems like such a basic problem. There's gotta be something I am missing here. By the way, I am using Python 2.7.13.

解决方案

This happens because Python (like most modern programming languages) uses floating point arithmetic, which cannot exactly represent some numbers (see Is floating point math broken?).

This means that, regardless of whether you're using Python 2, Python 3, R, C, Java, etc. you have to think about the effects of adding two floating point numbers together.

np.arange works by repeatedly adding the step value to the start value, and this leads to imprecision in the end:

>>> start = -1
>>> for i in range(1000):
...    start += 0.001
>>> start
8.81239525796218e-16

Similarly:

>>> x = np.arange(-1., 0.001, 0.01)
>>> x[-1]
8.8817841970012523e-16

The typical pattern used to circumvent this is to work with integers whenever possible if repeated operations are needed. So, for example, I would do something like this:

>>> x = 0.01 * np.arange(-100, 0.1)
>>> x[-1]
0.0

Alternatively, you could create a one-line convenience function that will do this for you:

>>> 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

But note that even this can't get around the limits of floating point precision; for example, the number -0.99 cannot be represented exactly in floating point:

>>> val = -0.99
>>> print('{0:.20f}'.format(val))
-0.98999999999999999112

So you must always keep that in mind when working with floating point numbers, in any language.

这篇关于numpy arange:如何制作“精确"浮点数数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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