Who knows, maybe it was a combination of mistakes that i did
@psyche good to see you have it working, the previous examples were vaild.
And just to be picky:
If you want to reconstitute a long type from char types, here is something that you can try beyond all the shifting / union.
unsigned char *uc_ptr; //unsigned char ptr, used for conversion
uc_ptr = (unsigned char *) &address; //point uc_ptr at the conversion results
*uc_ptr++=dat1; //assign the 1st char
*uc_ptr++=dat2; //assign the 2nd char
*uc_ptr++=dat3; //assign the 3rd char
*uc_ptr =dat4; //assign the 4th char
//after this point, address should contain the values represented by the four char types
Speed-wise, this will be as fast as the union approach and potentially faster. However, like the union approach, it is dependent on the compiler's endianess - so the code's portability is poor.
@dhnery, I hope there is more to come, most of your assumptions above are wrong. The task at hand is interlacing nibbles, more specifically 'un-serialisation' of data. The algorithm above is not intended for re-factoring and is almost guaranteed to be slower. One rule of thumb when designing an algorithm is assignments can be 'equal to' in speed compared to initialisations but never faster.
The algorithm above is typically used as a replacement for a loop, or used in conjunction with one, to trade off size for greater speed.
Also on a side note, most compilers suffer a small side effect relating to using a 'pointer to
' or 'reference of
' constant data, as a result these constants cannot be considered 'compile time constants
As for comparing the above to my union in reply #30
, just counting the operations shows it does less work before the compiler even gets to it.
Moving on to the versions in replies 15
, they are not quite as fast as the union due to their shifts greater than the native processor width, however they are faster than the above example too.
I haven't considered the union here
as its use of bit fields is very inefficient.
And as for them being non-portable, there is no reason to not include endianess handling into the struct which would give you portablility.
Hope this gives some thoughts.