我正在开发一款适用于
Windows和
Android的游戏,但它有一个我无法解决的问题.基本上我有一个带有一些按钮的4×5网格,这些按钮每秒填充一个必须为2,4或8的随机数.如果点击两个具有相同数字的按钮,则计算总和.这是一个firemonkey项目.
游戏运行正常,但您可以在下面的图片中看到问题.当我在我的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
> Android平板电脑: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;
解决方法
对于相同的浮点控制状态,浮点计算对于相同的输入是可重复的.
因此,使用三个不同的输入,您的表达式应具有三个不同的可能输因此,唯一的解释是某些东西改变浮点控制状态,例如,程序执行期间的舍入模式,精度等.
如果浮点运算可以精确地执行计算,则不需要舍入到整数.但是如果你必须四舍五入,至少使用Round而不是Trunc舍入到最近的.
也就是说,这绝对是执行随机选择2,4和8之一的离散任务的错误方法.这样做:
case Random(3) of 0: Result := 2; 1: Result := 4; 2: Result := 8; end;
另一种方法是将可能的输出放入一个数组中,然后像这样选择它们:
Result := arr[Random(3)];
当有更多值可供选择时,这会变得更有吸引力.
一个黄金法则是,如果你可以避免使用浮点这样做.浮点比整数算术更慢,更难以推理.仅在必要时使用它.