Reputation: 43
In an interrupt subroutine (called every 5 µs), I need to check the MSB of a byte and copy it to the rest of the byte.
I need to do something like:
if(MSB == 1){byte = 0b11111111}
else{byte = 0b00000000}
I need it to make it fast as it is on an interrupt subroutine, and there is some more code on it, so efficiency is calling.
Therefore, I don't want to use any if, switch, select, nor >>
operands as I have the felling that it would slow down the process. If i'm wrong, then I'll go the "easy" way.
What I've tried:
byte = byte & 0b100000000
This gives me 0b10000000
or 0b00000000
.
But I need the first to be 0b11111111
.
I think I'm missing an OR somewhere (plus other gates). I don't know, my guts is telling me that this should be easy, but it isn't for me at this moment.
Upvotes: 4
Views: 548
Reputation: 753
The MSB is actually the sign bit of the number. It is 1 for a negative number and 0 for a positive number. so the simplest way to do that is
if(byte < 0)
{
byte = -1;
}
else
{
byte = 0;
}
because -1 = 11111111 in binary.
If it is the case for an unsigned integer, then just simply type cast it into a signed value and then compare it again as mentioned above.
Upvotes: 0
Reputation: 6629
EDIT: My answer has confused people because I did not specify unsigned bytes. Here my assumption is that B
is of type unsigned char
. As one comment notes below, I can omit the &1
. This is not as fast as the signed byte solution that the other poster put up, but this code should be portable (once it is understood that B
is unsigned type).
B = -((B >> 7)&1)
Negative numbers our are friends. Shifting bits should be fast by the way.
Upvotes: 3
Reputation: 726849
The trick is to use a signed type, such as int8_t
, for your byte
variable, and take advantage of sign extension feature of the shift-right operation:
byte = byte >> 7;
Shifting right is very fast - a single instruction on most modern (and even not so modern) CPUs.
The reason this works is that >>
on signed operands inserts the sign bit on the left to preserve the sign of its operand. This is called sign extension.
Note: Technically, this behavior is implementation-defined, and therefore is not universally portable. Thanks, Eugene Sh., for a comment and a reference.
Upvotes: 3