随机变化的Java变量
我正在Windows 7上的Eclipse中开发一个粒子引擎,我遇到了一个以前从未见过的问题。 我的代码中有:随机变化的Java变量,java,opengl,lwjgl,Java,Opengl,Lwjgl,我正在Windows 7上的Eclipse中开发一个粒子引擎,我遇到了一个以前从未见过的问题。 我的代码中有: float start = startPosition.getY(); p.position.addTo(p.moveVector); float end = startPosition.getY(); if(start != end){ System.out.println("hit"); } 而且它确实经常被打印出来。 我这样做的原因是因为开始位置被改变了,它把我的程序搞砸了
float start = startPosition.getY();
p.position.addTo(p.moveVector);
float end = startPosition.getY();
if(start != end){
System.out.println("hit");
}
而且它确实经常被打印出来。
我这样做的原因是因为开始位置被改变了,它把我的程序搞砸了
我还进入了调试器,查看了打印机点击时的值,我得到了这个值作为end,position和movevevector中的所有变量:1.0E-5
我不知道该怎么办
这是我的密码
粒子发射器
粒子
向量3f
正在讨论的代码位于particleMitter的底部
如果您想查看或了解任何其他信息,请告诉我,但我认为这些都是相关信息。要回答您的第一个问题,1.0E-5基本上是零 总的来说,我认为您的问题在于您试图比较
float
变量是否相等,这从来都不是一件好事。我的猜测是,这些值实际上并没有“改变”,而是每次运行用于start
和end
的浮点近似值时,它们的表示方式都有点不同。这将解释您所看到的行为,即同一代码每次的行为似乎都有点不同
有关更多详细信息,请查看此链接:
回答第一个问题,1.0E-5基本上是零 总的来说,我认为您的问题在于您试图比较
float
变量是否相等,这从来都不是一件好事。我的猜测是,这些值实际上并没有“改变”,而是每次运行用于start
和end
的浮点近似值时,它们的表示方式都有点不同。这将解释您所看到的行为,即同一代码每次的行为似乎都有点不同
有关更多详细信息,请查看此链接:
您的particleMiter构造函数创建了一组粒子对象,其中startPosition作为每个对象的位置 Java按引用传递对象[共享对象(对象“引用”按值传递,因此每个人共享同一个对象)],因此每个粒子实例都引用相同的向量3f对象作为其位置 当您执行p.position.addTo(…)时,您正在更改粒子的所有位置以及起始位置 调用粒子构造函数时,需要克隆位置 编辑: 克隆只是“构建具有相同值的新对象”的一个术语。您可以通过以下方式逐个执行此操作:
new Vector3f(startPosition.x, startPosition.y, startPosition.z)
而不是起始位置
但这不是很健壮,因为如果Vector3f要获得一些状态,您需要更新这些调用。请参阅以获取一个接口,该接口允许您只调用startPosition.clone()
。[呃,大脑冻结]
编辑2:或者如前所述,在Vector3f上放置一个构造函数,该构造函数采用Vector3f参数。然后,当您将位置传递给粒子构造函数时,您的代码将变为新矢量3f(startPosition)。粒子混合器构造函数将创建一组粒子对象,其中startPosition作为每个粒子的位置 Java按引用传递对象[共享对象(对象“引用”按值传递,因此每个人共享同一个对象)],因此每个粒子实例都引用相同的向量3f对象作为其位置 当您执行p.position.addTo(…)时,您正在更改粒子的所有位置以及起始位置 调用粒子构造函数时,需要克隆位置 编辑: 克隆只是“构建具有相同值的新对象”的一个术语。您可以通过以下方式逐个执行此操作:
new Vector3f(startPosition.x, startPosition.y, startPosition.z)
而不是起始位置
但这不是很健壮,因为如果Vector3f要获得一些状态,您需要更新这些调用。请参阅以获取一个接口,该接口允许您只调用startPosition.clone()
。[呃,大脑冻结]
编辑2:或者如前所述,在Vector3f上放置一个构造函数,该构造函数采用Vector3f参数。当您将位置传递给粒子构造函数时,您的代码将变成
newvector3f(startPosition)
。我怀疑它们是“随机变化的”(这将是一个严重的错误,会使Java/JVM不适合任何严重的开发)。那么,暂时消除这种想法,这种行为还有什么其他可能性?startPosition
和position
可能是同一个对象吗?如果不是,它们是否会变异/更新相同的变量?或者,是否涉及到线程?现在让我们看看。。。要么java根本上有缺陷,要么代码中有缺陷。哎呀,真是太难了!我建议将断点放在相关对象的setter中,并检查调用堆栈以查看谁在设置值。你可能会发现它们为什么“随机”变化。此外,sgusc的回答有很好的信息。尝试打印开始
和结束
之间的差异:您可能会发现它很小,因此是浮点算术的人工制品问:是否可能您有一个线程(或多个线程!)您没有告诉我们,这可能是在背后更新值;)?另外:正如sgusc正确指出的,您无法可靠地比较两个浮点值的精确相等性。这适用于任何语言中的任何浮点实现:但对于(单精度)“浮点”值尤其如此希望对你有帮助。。PSMI认为这里有一个更根本的问题。使用==或!=比较两个float
变量永远不会像您希望的那样工作。如果在修复之后它仍然表现出奇怪的行为,那么线程是一个更可能的原因。事实上Elec是这样问的,而不是发布错误报告,这表明它们是一个错误