Libgdx可以在其坐标系中存储非常大的数字吗?

问题描述:

我想用一个科学准确的太阳系写游戏,并试图找出在大规模使用坐标的最佳方法。当我读到Libgdx中的坐标系时,它说它使用“浮点”来存储坐标数据。Libgdx可以在其坐标系中存储非常大的数字吗?

我希望厘米精确度达到约55亿公里,即小数点后12位。恐怕这个大的坐标不准确。

有人可以对此有所了解吗?

+0

我看到的所有Libgdx API都使用float而不是double。 –

+0

@StephenC它能够准确地存储小数点后12位吗? –

+0

如果API仅支持“float”,那么他们是否会以更高的精度“存储”事物是没有意义的。 (你知道Java float类型的精度是多少......我假设,如果没有,你应该在跳入这个项目之前做一些自学习。) –

我从来没有使用libgdx库,但看看它的API(例如Vector3或Rectangle),它似乎使用float s。

浮筒

Java的float表示二进制科学记数法的数字,即,每个数字是由一个23位的有效数和一个8位指数表示。把它看作一种形式(就像你银行的转账表格,你必须写出你想转账多少钱)。在每个框中可以编写一个10float form

注:23 + 8 = 31,缺少的比特被用作数字的符号。在这个答案中,我们不处理负数或负指数。

精密

由于指数,花车获得更大的数字不太精确。一些例子:

10_000_000 == 1E7 != 1E7 + 1 == 1.0000001E7 == 10_000_001 
100_000_000 == 1E8 == 1E8 + 1 == 1.0000000E8 == 100_000_000 

在10 尾数不够精确代表的1

的差异让我们计算精度为你的使用情况,其中数字是不要大于5.5在厘米测量十亿公里:

5.5×10 9 公里= 5.5×10 14 厘米= 1.11110100001110001101101 010100000011 ×2 厘米

由于我们只有23位来表示该号码,它被近似为

1.11110100001110001101101 ×2 厘米 = 549'999'989'489'664厘米
= 5'499'999'894'896.64 m = 5'499'999'894.896 64千米

您将会失去100多公里的距离!

可能的解决方法

  • 使用利用double,而不是float另一个库。双打有一个52位有效数字,对于你的用例来说足够精确。
  • 每个位置使用两个float s:粗略位置和细粒度偏移(不推荐)。
  • 不要试图做到这一点。我怀疑任何人都可以在厘米级精确追踪外层太阳系中的物体。

理想情况下,你要创建your own version of a Vector它使用BigDecimal,因为你可以控制有效数的数量。由BigDecimal表示的数字的值因此是(无标度值×10标度),see Javadoc

这是一个很好的问题来弹出有趣的解决方案。

你的问题标签为libgdx,所以我的解决方案不会远离使用它。让我们在这里解决每个问题。

不管,它仍然是浮

首先,我要告诉你,无论怎样的定位精度(浮动,双),你有,libgdx的底层系统,将与float走在最后。看到它的SpriteBatch类,它使用float表示每当需要在屏幕上画东西时的位置,以及也根据float的位置以及它的位置的类Sprite类。

这意味着无论您的精度如何,东西都会在屏幕上绘制在float

精密

还没有使用floatdouble的事情,你会得到浮点计算错误。如果你不能一发不可收拾(我不太了解你的游戏需求),根据你的游戏是否有关位置或其他事情,那么你可能需要考虑使用BigDecimal。银行应用程序会使用这样的事情,因为由于四舍五入错误它不会丢失任何一点,客户可能会抱怨!

您可能会在游戏对象中维护BigDecimal。您通过它们更新其位置,而不是在libgdx中设置位置的正常方式。但是无论何时你需要画画,你都可以通过doubleValue()获得它的价值。为什么加倍而不是浮动?最好提供可用于游戏的最高精度,因此当浮点数不能100%精确地表示数字时,会尽可能减小误差。

BigDecimal为慢

小心作为BigDecimal比正常的浮点运算速度较慢。请参阅其基准herehere

解决办法

因为我看到,在一个时间点上,用户只能看到你的空间有限的区域内。或者,即使您可能有一张允许用户缩小图以查看整个区域的空间图,那时您并不需要精确度或精确度,但libgdx所做的默认方式已足够,并且不需要切换游戏库(其他人大多也会基于float)。

那是,你仍然可以使用float但使用BigDecimal或者只是String代表屏幕上出现任何大的科学价值不计算在影响在运行时的游戏性能涉及的原因。因此,我相信这可以让我们缩小巨大的距离,因此您可以用相同的意图来表示游戏对象,使其成为科学正确的。