2 byte ints from 4 bytes?

Started by
15 comments, last by Enigma 16 years, 11 months ago
I'm looking to save a fair amount of data in binary form, and was wondering how I can make the ints be 2 bytes instead of 4, even though I'm on a 64-bit dev machine? If I can save out only 2 byte ints, I'd almost halve the size of the files, which would be very useful. I'm hoping there's some compiler definition I can use? I'm really hoping it's not going to be a case of having to replace every int declaration with a new typedef. I'm using Visual C++ 2003. Or perhaps I can make some new file read/write methods that convert the data on the fly? Is it possible to get the data types from variables, then I could cast them to the appropriate types, and read/write to file?
------------------------------------------[New Delta Games] | [Sliders]
Advertisement
I thought shorts were 2 bytes on most x64 compilers?
If you really want to control the number of bytes a value takes, int, short etc. won't help much - not in any portable way anyway, so you're better off using typedefs of VS's __int16, __int32 etc (which is also non-portable, but at least it's explicit, and you can change the typedefs if you ever end up compiling on another platform).

What you definitely don't want to do is say to the compiler, "I want all my ints to be only two bytes!" because, assuming they are already four bytes long, anything in any part of any program you write would suddenly find it's using two bytes for ints instead of four... and I guarantee to you that will break stuff.

It sounds like the exact value types you're saving out should be __int16's instead of ints. (Or short, probably). Alternatively, at the time of saving, apply a static_cast<__int16> instead, though you'll need to check the values are definitely in the range -32768 to +32767 or you'll lose information. And, I'd definitely use something like typedef __int16 s16 ("signed 16-bit value", as opposed to u16, "unsigined 16-but value") to make future changes easier.

Your last question might be solved by reflection, but that's a very difficult and involved thing to do in C++. Basically you just want to change your file writing functions to write out the values in the most appropriate size.
So in theory I should simply be able to static_cast to __int16 when saving, then when loading, load them into __int16 vars and cast them back to regular ints for use in the rest of the program. The whole -32767 to +32767 won't be a problem - I've never been able to leave the mindset that an int is only 2 bytes anyway, so I always write code thinking that ints are restricted to 2 bytes.

At least that's not as much work as replacing all the int declarations with __int16 :)

Thanks for your help.
------------------------------------------[New Delta Games] | [Sliders]
#include <boost/cstdint.hpp>// yeah yeah, its the quickest way to make all existing code// use 16 bits.#define int int_least16_t;


boost.cstdint
Why not just store each int as a linked list of bytes! Where the highest bit indicates whether another byte follows or not. So small values can be stored in 1-3 bytes. The drawback is that huge values are store in 4 or even 5 bytes!
This is used in database systems a lot to *compress* integers.

cu,
Chris
Quote:Why not just store each int as a linked list of bytes!


Because, like many programmers, I'm extremely lazy :) That sounds like far too much work.
------------------------------------------[New Delta Games] | [Sliders]
Quote:Original post by Christian Weis
Why not just store each int as a linked list of bytes! Where the highest bit indicates whether another byte follows or not. So small values can be stored in 1-3 bytes. The drawback is that huge values are store in 4 or even 5 bytes!
This is used in database systems a lot to *compress* integers.

cu,
Chris


Surely not in a *linked list* (consider how much overhead there is per node), but rather in a "string" (in the ancient C sense) - except that instead of being null terminated, it's "clear high bit terminated" (and the terminator carries information).

And yes, I've used this scheme before (and then found it wasn't really appropriate to my situation). :)
Quote:Original post by Julian90
#include <boost/cstdint.hpp>// yeah yeah, its the quickest way to make all existing code// use 16 bits.#define int int_least16_t;


boost.cstdint


I'm fairly certain it's illegal to #define a reserved keyword (which is not to say some compiler's won't let you do it [rolleyes]).
Quote:Original post by Driv3MeFar
I'm fairly certain it's illegal to #define a reserved keyword (which is not to say some compiler's won't let you do it [rolleyes]).
AFAIK, it's perfectly legal. It's simple text substitution.

This topic is closed to new replies.

Advertisement