3Byte Two's Compliment

Hello,

is there a smart way to handle signed 24 bit integers ? (without using "if" etc.)

Seems gcc > 4.7 supports a uint24_t nad int24_t datatype.

My ADC returns 3 Bytes conversion result as int24_t.

wally

"Smart" is highly subjective.

A "simple" way is to hand it to a signed long.

dhenry,

“Smart” is highly subjective.

agree :slight_smile:

void setup() {
  
  Serial.begin(115200);
  
  Serial.println("signed 24bit test\n");    
  
  int32_t value[]={0x800000, 0xFFFFFF, 0x0, 0x000001, 0x7FFFFF}; 
// exp result     -8.388.608,    -1   ,  0 ,    +1   , 8.388.607   
  
 
  for(int i=0; i<5; i++) {
    Serial.print(value[i], HEX);
    Serial.print("\t");
    Serial.println(value[i], DEC);    
  } 
  Serial.print("___________________");

output:
signed 24bit test

800000 8388608 // expected -8.388.608
FFFFFF 16777215 // expected -1
0 0
1 1
7FFFFF 8388607


i’, playing around with bit manipulation (shift, toggle, etc.) but
it always end up in requirement to use an IF condition.

“smart” would be without ‘IF’ but a straight conversion line ( or 2)

wally

800000 8388608 // expected -8.388.608

You'd need to do the sign extension yourself, or get the compiler to do it for you, by starting with 32 bit signed vales and truncating to 24. e.g.int32_t value[]={0xFF800000, 0xFFFFFFFF, 0x0, 0x000001, 0x7FFFFF};

What about this:

1) left align the 3 bytes to an unsigned long type. Making sure the last byte is 0. 2) Point a signed long pointer to the unsigned type. 3) right shift the unsigned type.

How about this:

a signed long type = ((signed long) (value << 8)) >> 8;
Essentially the approach I outlined earlier. It creates a left aligned unsigned long type (32-bit). Then it cast it to signed long to preserve the signage. After that, you right shift it to return the right value.
See if it works.

dhenry,

this is exactly what i meant by "smart" :)

Thank you very much wally