Why is there no Shift Arithmetic Left
Bobb Fwed
Posts: 1,119
I am converting a 32 signed value to a 24-bit signed value and back again. But I need to use shift arithmetic left to complete the conversion, but it doesn't exist.
Why not?
(am I missing something obvious, like it won't work?)
Why not?
(am I missing something obvious, like it won't work?)
Comments
0b101011101 <<~ 5 == 10101110111111
Is that what you had it mind? It sounds instead like you meant
0b101011101 <<~ 3 == 111101000
(ie, the high bit remains the same regardless of the left arithmetic shift amount).
If you have a 24 bit number, the upper 8 bits are all the "sign bit" (in 2's complement). But, you don't really want to think of having a "sign" bit, since the number as a whole represents a negative or positive number. It's simply a convenience that the upper bit denotes negative or positive.
Could you post what you are trying to do?
Like I said, I understand if I just use the 24 bits I'm fine, if my value is always less than 23-bits + sign.
It works fine until the value is greater than 23-bits. I want to maintain the sign above all else. So if the method is supplied a 30-bit value, and I just take the 24-bits, but new sign bit is unknown. To maintain the sign (but not he value), I have to store bit 31, then set that to bit 23. Which is what I was hoping a shift arithmetic left/shift right combo would do.
I can't post exactly what I am doing, but it breaks down to this (not optimized or complete):
In your case, you should be able to use a logical shift left followed by an arithmetic shift right to change from a signed 24-bit value to a signed 32-bit value and an and with $FFFFFF to change from a signed 32-bit value to a signed 24-bit value. Your values can only range from -2^23 to +2^23-1 though. Anything else is invalid and is considered to result in an overflow. It's essentially what you seem to be doing already.
Thanks for the replies.
I'll make things work.
m2 := ((m1 << 8) - constant( |<8 - 1 ) * (m1 < 0)) -> 8
untested
Jonathan