Defining Awesome — Packing floats
  • Status Updates

  • Packing floats

    Written by . Posted at 9:58 am on February 21st, 2011

    This is a post for coders.

    Here are 4 useful inline routines to decrease the size of a float by 50% (from 4 bytes to 2 bytes). I use them to pack every float in the game that doesn’t need big precision. Actually none of them do. So positions, velocities, cursor points are all packed (starting from the next version).

    typedef unsigned short u16
    typedef signed short s16
    typedef float f32

    // packs floats in the range of 0.f -> 32776.f/base;
    // in this case base = 100.0f so range 0.f -> 327.76f
    // when packing floats in this way you need to make sure they stay in this range
    // that is the cost of packing

    inline void packfloatu16( f32 x, u16 &y, f32 base = 100.0f)
    assert( x <= 32776.f/base ); x = min( 32776.f/base, max( 0.0f, x ) ); y = x * base; } inline void unpackfloatu16( u16 x, f32 &y, f32 base = 100.0f) { y = (f32) x / base; } // the same routine as above for signed characters // this is very good for packing velocities, since they rarely // become very large inline void packfloats16( f32 x, s16 &y, f32 base = 100.0f) { assert( x <= -0.5f*32776.f/base ); assert( x >= 0.5f*32776.f/base );
    x = min( 0.5f*32776.f/base, max( -0.5f*32776.f/base, x ) );
    y = x * base;

    inline void unpackfloats16( s16 x, f32 &y, f32 base = 100.0f)
    y = (f32) x / base;

    If assert() doesn’t work on your system, replace it with ASSERT or whatever the equivalent is. You can also remove it entirely since it is only for debug.

    Be Sociable, Share!


    1. Simple but effective.

    2. Nice stuff.
      I would love to see how you handle animations.

    3. So you pack and unpack floats every frame? Isn’t it faster to just use them normally? I seriously doubt that there’s any real advantage to this.

    4. If you never need the precision of a float isn’t it smarter to use shorts in the first place? I also agree with Rivon. Now you need to do additional multiplications and divisions each frame. I think using them straight away is faster? What’s the main reason for this, using less memory, performance?

    5. If it really uses so much memory, than you should probably rethink the architecture of the engine and rewrite the code. Not use hackery of this type.

    6. Rivon: Link-Dead would work with fixed precision integers instead of floats. The reason I’m not doing that is I would have to recode a large portion of code. I can’t invest time in that right now.

    Post a comment.