【发布时间】:2016-12-21 22:16:28
【问题描述】:
我正在开发一款可在 Windows 和 Android 上运行的游戏,但它有一个我无法解决的问题。基本上我有一个带有一些按钮的 4x5 网格,这些按钮每秒填充一个必须是 2、4 或 8 的随机数。如果您点击两个具有相同数字的按钮,则会计算总和。这是一个火猴项目。
游戏运行良好,但您可以在下面的图片中看到问题。当我在我的 windows 机器上运行游戏时,它会生成 2、4 或 8。在 android 下它会生成 2、4、7 和 8。随机数是这样创建的:
valueToOutput := Trunc(Exp(Ln(2) * (1+Random(3))));
该变量保存要在按钮中显示的数字。为什么我在 windows 和 android 中得到不同的结果?这是两张截图
- Windows 32 位:http://prnt.sc/dmd1ry
- 安卓平板:http://prnt.sc/dmd5uj
我确信该函数是正确的,因为我已经绘制了它 (exp(ln(2)*(1+x)) = http://prnt.sc/dmdc3u) 并且当 x 为 0,1 或 2 时(= 当随机数是 0,1 或 2)。这可能是编译器的问题吗?
注意:我已经使用您在下面看到的解决方法解决了这个问题,但起初我使用了您在问题中可以看到的代码,我想了解发生了什么.
valueToOutput := Trunc(Exp(Ln(2) * (1+Random(3))));
//this will always give 2, 4 or 8
if valueToOutput = 7 then
valueToOutput := valueToOutput + 1;
【问题讨论】:
-
简单的
valueToOutput := 2 shl Random(3)怎么样?然后你可以跳过所有的浮点垃圾。 -
是的,当然,这是一个非常好的解决方案(也比乘法更快),但我想知道那个公式。我想知道这是否只是在 android 中的精度损失
-
Android 上的
sizeof(Extended)是什么?在 Win32 上是 10,但在 Win64 上是 8。也许在移动设备上也有类似的精度损失? Embarcadero 的 DocWiki 上没有记录。 -
相关Is floating point math broken? 但是这并不能解释为什么这个函数不是确定性的。
Random(3)应该返回 3 个可能的Integer值,这意味着没有其他变化的函数应该有 3 个可能的结果。我唯一能想到的可能是在调用之间改变 FPU 设置。这可能会导致内部值的细微差异,其中 pre-Trunc值略小于8注意:Trunc()丢弃了很多 值跨度> -
顺便说一句:我怀疑你可能会在不同的 Android 硬件上得到不同的行为。
标签: android delphi firemonkey