Does the logical bitwise operator & supports the d

Hi, a (may be) stupid question ;) Does the logical bitwise operator & supports the long datatype? I ask because i have trouble with a peace of code since i have changes the datatype to long.

Thanks horchi

Yes, the bitwise operators and the logical operators work with longs. If you are getting unexpected results doing bitwise operations, try using unsigned long variables.

If that doesn’t solve the problem, post a code fragment and say what you expect and what is going wrong.

here is the relevant part of the interrupt routine called by timer2:

      static unsigned long lastInputValue = 0;

      unsigned long mask, b;
      unsigned long value = lastInputValue;
      unsigned long inputValue = 0;
      byte changes = 0;

      // some code to set the inputValue out of the SPI bus
      // ...

      // detect the changes

      for (byte bit = 0; bit < 24; bit++)
         mask = 1 << bit;
         b = (inputValue & mask) ? 1 : 0;
         b = b << bit;

         if (((lastInputValue & mask) ^ b))
            if (b)
               value |= mask;
               value &= ~mask;


As long as inputValue fit in 2 bytes all works fine, if i set at least one bit of the third byte the loop detects 24 changes an all bits in vale will set to HIGH. I have removed the SPI bus code, and the bounce check in the loop. If i test this loop on a PC it works.


Have you tried to print intermediate results to the serial port so you can see what is actually going on? It would be interesting to see (lastInputValue & mask) and b for your test case that fails.


i now added this to the loop in case the if succeeds:

            debug(lastInputValue, "lastInputValue");
            debug(mask, "mask");
            debug(b, "b");
            debug(bit, "bit");

The debug routine:

void debug(unsigned long value, const char* msg = 0)

  if (msg)


Ant this is the result on the PC side:

21:09:53,158 <- [DEBUG:lastInputValue=3840;] (00000000:00000000:00001111:00000000)
21:09:53,168 <- [DEBUG:mask=4294934528;] (01111111:11111111:11111111:11111111)
21:09:53,189 <- [DEBUG:b=32768;] (00000000:00000000:10000000:00000000)
21:09:53,199 <- [DEBUG:bit=15;] (00000000:00000000:00000000:00001111)

the if condition first match at bit 15, the value of the mask is wrong, i don’t understand why all bits except the highest are ‘1’ :frowning:


after hours i have the solution ::slight_smile:

for (byte bit = 0; bit < 24; bit++)
mask = 1L << bit;
b = (inputValue & mask) ? 1 : 0;
b = b << bit;

The constant 1 is interpreted as a int, with the L modifier it works.

many thanks,

Well spotted!

it drives me crazy :o

now i extended the loop from 24 to 32 bit and the problem is back again, but only for the highest bit.
The result of all the following lines is identical:

mask = 1L << 31;
mask = 1UL << 31;
mask = (unsigned long)1 << 31;
and at last, even due to my desperation:
mask = (unsigned long)(((unsigned long)1) << 31);


But the result of
mask = 1UL << 30;
is as expected:

mask is an ‘unsigned long’

Thanks again

the seems to be a problem with the 'unsigned' long support, the result of the following line is identical to the problem above:

unsigned long x = 0xFFFFFFFF; debug(x);

(01111111:11111111:11111111:11111111) (0x7FFFFFFF)

deleted - i was wrong :-[

the problem was my code on pc side, i used atol() to convert the transmitted values instead of atoll(), and this returned a signed 4byte value, sorry for the confusion