3 byte numbers!? [in C++]

Started by
12 comments, last by GameDev.net 17 years, 11 months ago
I got no idea if there exists 3 byte numbers.. I just know of short int (2 bytes) & int (4 bytes) Please don't say:"Use an int!", because im making a network app that needs to send alot of 3 byte numbers. If there exists none (i have googeled), then is it possible to construct one? It must work with all C++ operations... There should exist.. I hope :)
Please comment my english!
Advertisement
Well number of bytes that a built in type takes up is platform dependant. But typically no there isnt one. The only solid solution i can think of is to write a class that manages 3 chars, overloads all the operators so that it can be added to things etc etc

Dave
Quote:Original post by masterviking
Please don't say:"Use an int!", because im making a network app that needs to send alot of 3 byte numbers.


And the problem with using an int (assuming a 32-bit int) to store the value and only transmitting the 3 lower bytes is.....what?
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Try using bitfields like this:
struct X{    unsigned int var : 24;};
You can work with an unsigned int like this:

void Encode(unsigned int a, char* pDest){	memcpy(pDest,&a,3);}unsigned int Decode(const char* pSrc){	unsigned int ret=0;	memcpy(&ret,pSrc,3);	return ret;}


But be aware that this will only work on little endian systems, where data is stored like this AABBCCDD where AA is the least significant byte. In that case the memcpy will take the first 3 bytes and copy them to the char buffer dropping the DD. So if you need something platform independant, you need to code seperate versions for both endianesses.
Presumably he's attempting to save 1 bytes by sending 3 byte positions or 3 byte IDs instead of going all out for a 4 byte integer.

There's no standard type that uses 3 bytes, though you could probably build on as a class, and override +,/,-,= etc to make it look like an intrinsic. I'm not certain it's a good idea; you might be better of just taking the hit for the 4 byte system, rather than taking a hit on conversion in and out (not to mention all the fun overflow errors you're opening yourself to).

Very often, the higher-level optimizations (deciding WHAT to send) is more important than the lower-level optimization (cut 8 bits from that number). You might get as good (or better) performance by running the packet through a compression algorithm as part of your packet-sender (either a simple huffman, or a more complex, zlib like, compression).

Allan
------------------------------ BOOMZAPTry our latest game, Jewels of Cleopatra
Quote:Original post by C0D1F1ED
Try using bitfields like this:
*** Source Snippet Removed ***


This won't work, since the basic type is int.

To create a 3 byte number, it is possible to create an overloaded class which stores three bytes (characters) internally. Since a characters size and alignment is 1, this will make a struct containing three of them have a size of 3 and an aligment of 1.
Use an int. Period. But use a method that does not write the uppermost byte
into the data stream if necessary. But use an int for any local computations. Otherwise you gain a byte on the network for a slow computation on both ends. Unless your network is a 1200 baud modem from the 80s, there is no rationale
for doing this.
Quote:Original post by starmole
Use an int. Period. But use a method that does not write the uppermost byte
into the data stream if necessary. But use an int for any local computations. Otherwise you gain a byte on the network for a slow computation on both ends. Unless your network is a 1200 baud modem from the 80s, there is no rationale
for doing this.
Seconded.

If you have a lot of 3-byte numbers in a struct, then you could use a bitfield like C0D1F1ED suggested, but that'll still be rounded up to the nearest sizeof(int) bytes. The main benifit is that if you have a number that ranges from 0-10, then you only need 4 bits to represent it, and you can pack 2 of those into 1 byte.
Thank you all for the answers!

This sounds perfect:
"
void Encode(unsigned int a, char* pDest)
{
memcpy(pDest,&a,3);
}

unsigned int Decode(const char* pSrc)
{
unsigned int ret=0;
memcpy(&ret,pSrc,3);
return ret;
}
"
!!!! thanx!

"And the problem with using an int (assuming a 32-bit int) to store the value and only transmitting the 3 lower bytes is.....what?"
Because I want to send a structure that contains 3 byte numbers + others.
& now that will work with the encoding techniqe.

+ Thank you for learning me bitfields! It will be very useful!
One can now define real bits now! that's nice :D (you know... the bool have the size of 1byte)
Please comment my english!

This topic is closed to new replies.

Advertisement