Google Answers Logo
View Question
 
Q: 24-bit unsigned int in ( No Answer,   2 Comments )
Question  
Subject: 24-bit unsigned int in
Category: Computers > Programming
Asked by: tomfinnigan-ga
List Price: $12.00
Posted: 17 Mar 2005 12:39 PST
Expires: 16 Apr 2005 13:39 PDT
Question ID: 496319
I'm trying to make a unsigned integer type in c/c++ that only takes 24 bits.  
A piece of sample code looks like this:
=======================
#include <stdio.h>
#pragma pack(push, 1)
struct test {
        unsigned int data : 24;
};
#pragma pack(pop)

int main( int, char** ) {
        printf( "Sizeof(test) = %d\n", sizeof( test ) );
        return 0;
}
=======================
Using gcc, the output is "Sizeof(test) = 3"
Using msvc7.1 and 6.0, the output is "Sizeof(test) = 4"

How can I get an integer that is 24bits, that I can treat like an
integer?  I can create a struct of 3 chars, which is 3 bytes, but that
doesn't meet my needs.  Basically, I want similar results out of
msvc7.1 as I get out of gcc.  Specifically, I need something that can
be incremented, converted to and from a 4-byte int, used as an index
into an array, and only takes 3 bytes of storage.

On msdn, they have some good information at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcepbguide5/html/wce50conworkingwithpackingstructures.asp
but they don't explain how to do what I need to.

Thanks.

Request for Question Clarification by maniac-ga on 17 Mar 2005 20:00 PST
Hello Tomfinnigan,

I could probably do what you want in Ada - something like
  type i24 is mod 2**24;
which defines a 24 bit unsigned integer, but there is nothing in that
language (or in C) that requires the compiler to align objects of that
type on a single byte (instead of a 4 byte boundary - which msvc7.1
appears to be doing). [Ada allows the 'size' of a type to be different
than the 'size' of an object]

What is your application?

For example, if you must read / write 3 bytes from a hardware device,
there may be a "better way" to do what you are asking for. Also - if
you could use gcc on your Windows platform, I could probably code up a
simple Ada package (callable from C) that would do the basic
operations as another alternative.

  --Maniac

Clarification of Question by tomfinnigan-ga on 18 Mar 2005 10:58 PST
The #pragma pack(1) tells the compiler to align structures on 1-byte 

boundaries, but different compilers interpret it differently - gcc aligns 

whole structs, while msvc will pack elements inside of structs.  For 

example, if you've got:

struct packme {
    char a;
    int  b;
}

If you use default packing, it'll be 8 bytes (because it aligns the int to 

word boundaries, and the order is bad), but if you pack it (or put the int 

first) it'll be 5 bytes.

My application is manipulation of large polygonal meshes - potentially 

several million polygons, and an arbitrary number of edges composing each 

face.  The manipulation I do requires creation of various temporary groups 

of indices, such as sets, maps, vectors, etc.  I use the STL extensively.
Also involved is loading large binary files from disk into a vector of
these objects as a single read().  I've gotten this all working with
gcc, but when I was porting my stuff to msvc, it didn't work.

So, the short answer is that both the space and the speed are important.

I'll have to run some experiments, but I think that perhaps I might be
able to have one class that has 3 chars, but where all of its
operators cast a pointer to the internal struct to another one which
has the 24-bit int, and operates on that instead.  If I understand the
compilation correctly, the cast will be free, although it'll likely be
unaligned.
Answer  
There is no answer at this time.

Comments  
Subject: Re: 24-bit unsigned int in
From: mathtalk-ga on 17 Mar 2005 20:06 PST
 
It seems to me the simplest implementation would be to define
"overloaded" operators on a 3-byte structure by using a (4
byte/32-bit) integer that the 3 bytes define (in least significant
positions) to do every required operation, then repack the least
significant three bytes back into the structure as a result.

So "incrementing" the 24-bit pointer becomes:

 - move 3 bytes to scratch integer "working variable"
 - increment the "working variable" integer
 - repack the 3 bytes in 24-bit structure

Larger offset & decrementing would be handled similarly through
integer arithmetic, as might be detecting/throwing over- and underflow
exceptions.

Naturally there's a fair amount of data-movement overhead implied by
this scheme, but it should be quite portable.  It's not essential that
the "working variable" be merely 32 bits, of course, and on a 64-bit
architecture the most efficient datatype would probably be the natural
word size.

I say portable because you can see that the storage of three bytes can
in principle be managed whether the architecture is big endian or
little endian.  The trickier aspect is presumably the compiler options
to allow structures _not_ to be aligned on word boundaries, and this
might actually contribute (depending on how many "odd sized"
structures need to be read or moved) to a larger overhead than the
packing/unpacking aspect, since the alignment options potentially
affect the efficiency of more of what the program has to do.

regards, mathtalk-ga
Subject: Re: 24-bit unsigned int in
From: mathtalk-ga on 18 Mar 2005 13:39 PST
 
If you need a lot of these (and I imagine you do, or it wouldn't be an
issue), then consider packing these in pairs.  Two odd-byte structures
can easily be made to coexist on a word boundary.

regards, mathtalk-ga

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy