1

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非常大,但我想知道精度问题将如何发挥作用。

根据我的理解,afloat使用 1 位存储符号,使用 8 位存储指数,使用 23 位存储尾数(假设前导 1):

    S EEEEEEEE MMMMMMMMMMMMMMMMMMMMMMM

这意味着FLT_MAX可能看起来像:

    0 11111111 11111111111111111111111

这相当于:

1.11111111111111111111111 x 2^128

或者

111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

即使知道这一点,我也很难想象精度的损失,而且我对随着值的不断增加会发生什么感到困惑。

有没有更简单的方法来思考这个问题?是否floatsdoubles通常用于在类似的东西上存储非常大的数字unsigned int

4

4 回答 4

3

考虑浮点数精度的一种方法是认为它们具有大约 5 位数的精度。因此,如果您的单位是米,并且您有 1 公里以外的东西,那就是 1000 米 - 尝试以 10 厘米(0.1 米)或更小的分辨率处理该物体可能会出现问题。

游戏中的常用方法是使用浮点数,但将世界划分为相对于局部坐标系的位置(例如,将世界划分为一个网格,每个网格正方形都有一个平移值) . 一切都将具有足够的精度,直到它相对于相机进行转换以进行渲染,此时远处物体的不精度不是问题。

例如,想象一下太阳系中的游戏。如果你的坐标系的原点是在太阳的中心,那么行星表面的坐标就不可能用浮点数准确地表示出来。然而,如果你有一个相对于行星表面的坐标系,而后者又是相对于行星的中心,然后你知道行星相对于太阳的位置,你就可以在局部空间中对事物进行操作准确,然后转换为您想要渲染的任何空间。

于 2012-12-06T12:08:20.090 回答
0

不,他们不是。

假设自从游戏对象移动后,您的位置需要在某个帧增加 10 厘米。

假设游戏世界以米为单位,则为 0.10。但是,如果您的float值足够大,它将无法再表示 0.10 的差异,并且您增加该值的尝试将完全失败。

于 2012-12-06T12:04:04.237 回答
0

是否需要用小数部分存储大于 16.7m 的值?那么浮动会太小。

Bruce Dawson 的这个系列可能会有所帮助

于 2012-12-06T12:05:10.787 回答
0

如果您确实需要处理非常大的数字,请考虑使用任意精度算术库。您将不得不分析您的代码,因为这些库比内置类型的算术要慢。

您可能并不需要非常大的坐标值。例如,您可以环绕世界的边缘,并使用模运算来处理位置。

于 2012-12-06T12:09:21.120 回答