Take the 2-minute tour ×

I have tried to make a longer function but it has acted very weird. I had tried to isolate the problem and I have been able to find the buggy part.

This program made for an Arduino but this phenomenon probably appear in other environment. I have tried to make a lot of searches but I cannot find the solution.

So, my buggy part:

Why do not these two codes give the same result?
How can I construct a one line function without extra variable
but same operation like "Code 1"?


  • Code 1: 0b00101100
  • Code 2: 0b01101100

Source codes:

Code 1: (correct operation but not one line)

#include <binary.h>

const byte value=B00110110;
byte buffer,result;

void setup(){

  buffer = (value << 3);
  result = (buffer >> 2);


void loop(){

It gives: 0b00101100

Code 2: (incorrect operation but one line)

#include <binary.h>

const byte value=B00110110;
byte result;

void setup(){

  result = ((value << 3) >> 2);


void loop(){

It gives: 0b01101100

share|improve this question
What is byte? –  AndreyT Jul 25 '12 at 19:18
OH, Type promotion! I was totally at dead end. I thought there was something wrong with shift handling. Thank all of you so much ! –  osiixy Jul 26 '12 at 18:58

3 Answers 3

up vote 2 down vote accepted

I assume that your byte is some unsigned integral type smaller than int.

Most arithmetic operations in C++ are performed in the domain of int type, after all "smaller" operands are implicitly converted (promoted) to type int.

For this reason, your first group of shifts is equivalent to

buffer = (byte) ((int) value << 3);
result = (byte) ((int) buffer >> 2);

while your second group if shifts is equivalent to

result = (byte) (((int) value << 3) >> 2);

In the first variant, any bits that get shifted outside the range of type byte by the << 3 shift are lost during intermediate conversion and assignment to buffer. In the second variant all calculations are performed within the range of int, so nothing is lost.

If you want your second variant to produce the same results as the first, you need to explicitly "truncate" the intermediate shift result

result = ((byte) (value << 3) >> 2);
share|improve this answer

Remove the extra bits by masking with 0xFF:

result = (((value << 3) & 0xFF) >> 2);

You can also trim the upper three bits off after the sequence of shifts:

result = 0x1F & ((value << 3) >> 2);

According to the language specification, default integer promotions are applied to shift operands before shifting, and the result of the operation is the promoted type of the first operand.

5.8.1 The operands shall be of integral or enumerated type and integral promotions are performed. The type of the result is that of the promoted left operand.

If an integral type can fit in an int, then int is the result of the promotion. When you shift left, the most significant bits "spill" into the upper part of the int. Your first snippet cuts them off by assigning back to byte; you can achieve the same result by masking the result with 0xFF.

Link to ideone.

share|improve this answer

If byte is a uint8_t (thanks Mr. Fernandes!), the result of (value << 3) is wider than a byte. More precisely, value is promoted to a wider type before the shift occurs, and the result is that wider type. To get the behavior of Code 1, you can change Code 2 to do this:

result = (static_cast<byte>(value << 3) >> 2);

This mimics the intermediate assignment to buffer in Code 1 with a cast.

share|improve this answer
Not just "likely", it's certain: the operands get promoted to int. –  R. Martinho Fernandes Jul 25 '12 at 19:12
@R.MartinhoFernandes: Yes, if byte is integral, but it might be a class. I can't tell. –  jxh Jul 25 '12 at 19:13
Ah good point. But I suspect it's this byte here: code.google.com/p/arduino/source/browse/trunk/hardware/arduino/… –  R. Martinho Fernandes Jul 25 '12 at 19:18
@R.MartinhoFernandes: Thanks, answer updated. Regards –  jxh Jul 25 '12 at 19:24

Your Answer


