C++ 将3D矢量浮点点压缩为无符号整数并将其解压

C++ 将3D矢量浮点点压缩为无符号整数并将其解压,c++,bit-manipulation,C++,Bit Manipulation,GetPacked将把一个3D点打包成一个无符号整数。我想把它解包回点,但不起作用。请帮忙 uint32_t GetPacked(float x, float y, float z) { return ( 0xff000000 | ( ( uint32_t ) ( ( x * 127.5f ) + 127.5f ) << 16 ) | ( ( uint32_t ) ( ( y * 127.5f ) + 127.5f ) <<

GetPacked将把一个3D点打包成一个无符号整数。我想把它解包回点,但不起作用。请帮忙

uint32_t GetPacked(float x, float y, float z)
{   
    return ( 0xff000000 
        | ( ( uint32_t ) ( ( x * 127.5f ) + 127.5f ) << 16 )
        | ( ( uint32_t ) ( ( y * 127.5f ) + 127.5f ) << 8 ) 
        | ( ( uint32_t ) ( ( z * 127.5f ) + 127.5f ) ) );
}
谢谢


注:我在

中创建了一个在线测试,您将失去精度

// a, b, b in the range of -127.5 +127.5

uint32_t Code(float a, float b, float c)
{
    union
    {
        uint32_t u32;
        uint8_t u8[4];
    } u;

    u.u8[3] = 0xff;
    u.u8[0] = a + 127.5f;
    u.u8[1] = b + 127.5f;
    u.u8[2] = c + 127.5f;

    return u.u32;
}

void DeCode(uint32_t u32, float *a, float *b, float *c)
{
    union
    {
        uint32_t u32;
        uint8_t u8[4];
    } u;

    u.u32 = u32;
    *a = (float)u.u8[0] - 127.5f;
    *b = (float)u.u8[1] - 127.5f;
    *c = (float)u.u8[2] - 127.5f;
}


int main(void)
{
    float a = 102.3f, b = -56.4f, c = -126f, d,e,f;

    uint32_t coded = Code(a, b, c);
    DeCode(coded, &d, &e, &f);

    printf("Original values: %f,%f,%f. Coded -%x. Decoded %f,%f,%f\n", a, b, c, coded, d, e, f);
}
为了获得更好的精度,您可以将其缩放到10位

#define B10MAX      ((float)((1u << 10) - 1))
float Scale(float x)
{
    return B10MAX * (x + 127.5f) / 255.0f;
}

float DeScale(unsigned x)
{
    return 255.0f *(x) / B10MAX - 127.5f;
}

uint32_t Code10(float a, float b, float c)
{
    union
    {
        uint32_t u32;
        struct
        {
            uint32_t value1 : 10;
            uint32_t value2 : 10;
            uint32_t value3 : 10;
        };
    } u;

    u.value1 = Scale(a);
    u.value2 = Scale(b);
    u.value3 = Scale(c);

    return u.u32;
}

void DeCode10(uint32_t v, float *a, float *b, float *c)
{
    union
    {
        uint32_t u32;
        struct
        {
            uint32_t value1 : 10;
            uint32_t value2 : 10;
            uint32_t value3 : 10;
        };
    } u = {.u32 = v,};

    *a = DeScale(u.value1);
    *b = DeScale(u.value2);
    *c = DeScale(u.value3);
}
#define B10MAX      ((float)((1u << 10) - 1))
float Scale(float x)
{
    return B10MAX * (x + 127.5f) / 255.0f;
}

float DeScale(unsigned x)
{
    return 255.0f *(x) / B10MAX - 127.5f;
}

uint32_t Code10(float a, float b, float c)
{
    union
    {
        uint32_t u32;
        struct
        {
            uint32_t value1 : 10;
            uint32_t value2 : 10;
            uint32_t value3 : 10;
        };
    } u;

    u.value1 = Scale(a);
    u.value2 = Scale(b);
    u.value3 = Scale(c);

    return u.u32;
}

void DeCode10(uint32_t v, float *a, float *b, float *c)
{
    union
    {
        uint32_t u32;
        struct
        {
            uint32_t value1 : 10;
            uint32_t value2 : 10;
            uint32_t value3 : 10;
        };
    } u = {.u32 = v,};

    *a = DeScale(u.value1);
    *b = DeScale(u.value2);
    *c = DeScale(u.value3);
}
coded = Code10(a, b, c);
DeCode10(coded, &d, &e, &f);

printf("Original values: %f,%f,%f. Coded = %x. Decoded %f,%f,%f\n", a, b, c, coded, d, e, f);