我正在使用floats
代表游戏中的位置:
struct Position
{
float x;
float y;
};
我想知道这是否是最好的选择,以及随着头寸价值继续扩大而带来的后果。我花了一些时间来了解浮子的储存情况,并意识到我有点困惑。
(我正在使用Microsoft Visual C ++编译器。)
在float.h
中,FLT_MAX
的定义如下:
#define FLT_MAX 3.402823466e+38F /* max value */
是340282346600000000000000000000000000000
。
该值远大于UINT_MAX
,其定义为:
#define UINT_MAX 0xffffffff
并且对应于值4294967295
。
基于此,似乎float
是一个很好的选择,可以存储像位置这样的非常大的数字。尽管FLT_MAX
非常大,但我想知道精确度问题将如何发挥作用。
根据我的理解,float
使用1位来存储符号,8位用于存储指数,23位用于存储尾数(假设前导1):
S EEEEEEEE MMMMMMMMMMMMMMMMMMMMMMM
这意味着FLT_MAX
可能如下:
0 11111111 11111111111111111111111
这相当于:
1.11111111111111111111111 x 2^128
或
111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
即使知道这一点,我也无法想象精确度的损失,而且我很困惑地想着随着价值的不断增加会发生什么。
有没有更简单的方法来考虑这个? floats
或doubles
通常用来存储unsigned int
之类的大数字吗?
答案 0 :(得分:3)
考虑浮子精度的一种方法是考虑它们具有大约5位数的精度。因此,如果你的单位是米,并且你有1公里远的东西,那1000米 - 试图以10厘米(0.1米)或更小的分辨率处理该物体可能会有问题。
游戏中常用的方法是使用花车,但要将世界分开,使得位置相对于局部坐标系统(例如,将世界划分为网格,并且每个网格方块都有翻译价值)。一切都将具有足够的精度,直到它相对于相机进行变换以进行渲染,此时远距离物体的不精确性不是问题。
作为一个例子,想象一下在太阳系中设置的游戏。如果你的坐标系的原点位于太阳的中心,那么行星表面上的坐标就不可能在浮点数中准确表示。但是,如果你有一个相对于行星表面的坐标系统,而该行星表面相对于行星的中心,然后你知道行星相对于太阳的位置,那么你可以对局部空间中的事物进行操作准确无误,然后转换为您想要渲染的任何空间。
答案 1 :(得分:0)
不,他们不是。
假设游戏对象移动后,你的位置需要增加10厘米。
假设游戏世界以米为单位,则为0.10。但是,如果您的float
值足够大,则无法再表示0.10的差异,并且您尝试增加该值只会失败。
答案 2 :(得分:0)
您是否需要使用小数部分存储大于16.7米的值?然后浮动太小了。
答案 3 :(得分:0)
如果您确实需要处理非常大的数字,请考虑使用arbitrary-precision arithmetic library。您将不得不分析您的代码,因为这些库比内置类型的算术慢。
您可能不需要非常大的坐标值。例如,您可以环绕世界的边缘,并使用modulo arithmetic来处理位置。