Pages: [1]   Go Down
Author Topic: 3Byte Two's Compliment  (Read 659 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

"Smart" is highly subjective.

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

0
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dhenry,

Quote
"Smart" is highly subjective.
agree smiley

Code:
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
 



Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26344
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Code:
int32_t value[]={0xFF800000, 0xFFFFFFFF, 0x0, 0x000001, 0x7FFFFF};
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How about this:

a signed long type = ((signed long) (value << smiley-cool) >> 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.
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 148
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dhenry,


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

Thank you very much
wally
Logged

Pages: [1]   Go Up
Jump to: