【问题标题】:Python floating point [duplicate]Python浮点[重复]
【发布时间】:2012-10-11 12:01:23
【问题描述】:

可能重复:
Floating point equality in python

我的 Python 代码有一个小“问题”(我现在在 ika 游戏引擎中使用 2.5 版)。我目前为我的游戏编写对象,我想知道比较两个浮点数是否安全这种方式:

我将做一个简短的例子来说明我目前的工作。

每个对象都有一个速度,从 0 到 9,以浮点数表示。例如

speed = 4.83
cord_x = 10.0
cord_y = 10.0

他们有一个 AddMovement 方法。这会设置 X、Y 值,并表示对象的目标坐标。

target_x = 25.0
target_x = 26.75
movement = True # This represents if the object is moveing or not

每一帧,最大速度等于这个值:

maximum_x_speed = abs(cord_x-target_x)
maximum_y_speed = abs(cord_y-target_y)

而真正的速度是:

# Get the real X speed in this frame
if maximum_x_speed < speed:
    real_x_speed = maximum_x_speed
else:
    real_x_speed = speed

# Get the real Y speed in this frame
if maximum_y_speed < speed:
    real_y_speed = maximum_y_speed
else:
    real_y_speed = speed

现在,根据这个 real_x_speed 值和 real_y_speed 值,我从坐标中减去这个值。

if target_x < cord_x:
    cord_x -= real_x_speed
elif target_x > cord_x:
    cord_x += real_x_speed
if target_y < cord_y:
    cord_y -= real_y_speed
elif target_y > cord_y:
    cord_y += real_y_speed

最后,我检查是否相等

if cord_x == target_x and cord_y == target_y:
    # Halt movement, reached goal
    movement = False

我过去曾遇到过浮点错误,例如 0.1 问题,并且……我担心这会导致某种错误。或者这在逻辑上是不可能的?

如果我有语法错误,对不起。英语不是我的母语... 如果我应该改变这个逻辑,我真的很感激一些提示。

【问题讨论】:

  • 什么是“0.1”问题?您是浮点错误、异常还是在您认为应该的时候说两个认为不相等?
  • 两个东西不相等。前段时间我有一个案例,当我将 0.1 加在一起 ​​10 次时,并检查它是否等于 1.0。

标签: python


【解决方案1】:

不,这种类型的代码绝不是一个好主意。

会有累积的浮点错误,使其很难跟踪。您确实应该使用“epsilon”方法,即如果差值小于某个设置常量(通常称为epsilon),则认为这两个值相等:

def floats_equal(x, y, epsilon = 1e-4):
  return abs(x - y) < epsilon

当然,您必须根据应用程序的需要调整 epsilon 值,但值表示基于像素的位置的游戏不需要太高的精度。

请注意,正如其他答案中所指出的那样,有一个 最小 epsilon 可以在机器上运行,但通常最好使用应用程序级 epsilon,例如以上。出于演示目的在 2D 像素空间中插值时,很少有任何精度为 2.22044604925 * 10-16 的点,这恰好是我本地系统上 sys.float_info.epsilon 的值。

【讨论】:

  • 谢谢!实际上 epsilon = 0.01 在我的情况下也可以工作(我现在对此进行了测试)。该对象将使用整数值进行渲染,因此基本看不到差异。
【解决方案2】:

这样做通常会更好:

EPSILON = 0.00001 # or whatever 

if abs(cord_x - target_x) < EPSILON and abs(cord_y - target_y) < EPSILON:
    # Halt movement, reached goal
    movement = False

有些人选择EPSILON为:

import sys

sys.float_info.epsilon

1 和大于 1 的最小值之间的差值可以表示为浮点数 - here

【讨论】:

    【解决方案3】:

    简短的回答是你所做的很糟糕。长答案是正确的方法取决于你在做什么。看看几种比较浮点数的不同方法:

    http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

    如果您使用浮点数,则值得通读全文。

    【讨论】:

      猜你喜欢
      • 2011-02-28
      • 2011-08-10
      • 2013-08-10
      • 2013-11-03
      • 2017-08-16
      • 1970-01-01
      • 1970-01-01
      • 2015-04-02
      • 2018-04-29
      相关资源
      最近更新 更多