使用浮动来存储大数字

时间:2012-12-06 12:00:11

标签: c++ precision

我正在使用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

即使知道这一点,我也无法想象精确度的损失,而且我很困惑地想着随着价值的不断增加会发生什么。

有没有更简单的方法来考虑这个? floatsdoubles通常用来存储unsigned int之类的大数字吗?

4 个答案:

答案 0 :(得分:3)

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

游戏中常用的方法是使用花车,但要将世界分开,使得位置相对于局部坐标系统(例如,将世界划分为网格,并且每个网格方块都有翻译价值)。一切都将具有足够的精度,直到它相对于相机进行变换以进行渲染,此时远距离物体的不精确性不是问题。

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

答案 1 :(得分:0)

不,他们不是。

假设游戏对象移动后,你的位置需要增加10厘米。

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

答案 2 :(得分:0)

您是否需要使用小数部分存储大于16.7米的值?然后浮动太小了。

This series by Bruce Dawson may help

答案 3 :(得分:0)

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

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