Help deciphering this if statement code snippet?.

Hi I am trying to understand this if statement.

----------------------------------------------
volatile unsigned char idx = 4; 
volatile unsigned int BASE[4] = {0x8000, 0x8000, 0x8000, 0x8000};

idx = 2;   
if ( ! ( ( (unsigned char*)&BASE[idx])[1] & 0x80) ) 
{  .... 
------------------------------------------------

I think this reads something like
if not(some value)and0x80) then

I think. I am good with this comparing for the mystery value to be <> 0x80 ?

It looks to me like it’s reading the high order byte of the integer base(i).

What does the [1] do? This is kind of confusing me.

Thanks, Richard

----------------------------------------------
volatile unsigned char idx = 4;
volatile unsigned int BASE[4] = {0x8000, 0x8000, 0x8000, 0x8000};
//                                                 ^^
//                                                 ^^

idx = 2;  
if ( ! ( ( (unsigned char*)&BASE[idx])[1] & 0x80) )
{  ....
------------------------------------------------

The if statement returns false if the marked byte (^^) is 0x80

Experiment with it yourself by changing the value, or print it out, and see what happens:

Serial.println ( ( (unsigned char*)&BASE[idx])[1] , HEX) ;

The [1] is treating the original unsigned integer 0x8000 as an array of two bytes 80 00 The order is inverted because of , I believe, the issue alluded to here: http://betterexplained.com/articles/understanding-big-and-little-endian-byte-order/ I'm also interested in this and I hope you get a better answer.

Ok, that kind of helps me..

( (unsigned char*) & BASE[idx]) [1]

is the 2nd element of an unsigned 2 byte array.

char* pointer is loaded with the address of the &BASE(n).

Arduino stores in LSB, MSB sequence, so element [1] is the MSB.

So the if tests the MSB of BASE(n) "AND" 0x80 to test if bit 7 is "not" on... ?

Exactly. That is how I understand it. Bit 7 (that is, bit 15 of the original integer) must be 0 for the if statement to return true.

Looks like a probe of runtime endian order.

6v6gt:

```

volatile unsigned char idx = 4; volatile unsigned int BASE[4] = {0x8000, 0x8000, 0x8000, 0x8000}; //                                                ^^ //                                                ^^

idx = 2;  if ( ! ( ( (unsigned char*)&BASE[idx])[1] & 0x80) )

{  ....




The if statement returns false if the marked byte (^^) is 0x80

Experiment with it yourself by changing the value, or print it out, and see what happens:

Serial.println ( ( (unsigned char*)&BASE[idx])[1] , HEX) ;

The [1] is treating the original unsigned integer 0x8000 as an array of two bytes 80 00 
The order is inverted because of , I believe, the issue alluded to here:
http://betterexplained.com/articles/understanding-big-and-little-endian-byte-order/
I'm also interested in this and I hope you get a better answer.
The if statement returns false if the marked byte (^^) is 0x80

Not quite.... it returns false if the MSB of that byte is set. It doesn't matter what the other 7 bits are.

Regards, Ray L.

6v6gt: Exactly. That is how I understand it. Bit 7 (that is, bit 15 of the original integer) must be 0 for the if statement to return true.

Bit 15 is the sign bit of a signed integer. Looks like a long-winded way of checking whether the number is negative or positive.

volatile unsigned int BASE[4] = {0x8000, 0x8000, 0x8000, 0x8000};

if ( ! ( ( (unsigned char*)&BASE[idx])[1] & 0x80) ) 
{  ....

Henry_Best:
Bit 15 is the sign bit of a signed integer.
Looks like a long-winded way of checking whether the number is negative or positive.

This code runs in a interrupt and needs to be fast. I assume the original author possibly did it this way for speed?

Why not cast this as integer and check if < 0, as you suggest?

The interrupt runs at 20hz.

How could I time the execution speed of the interrupt?

Rich

I thought you had found an old C++ exam/certification question from somewhere. There must be less convoluted methods of achieving the same thing.

No Exam,

Any thought how to time the execution time of an interrupt that is happening 20,000 times per second?

Hi Again,

I put this routine into a 100 iteration loop and used micros() to get times.

    // if (!(((unsigned char*)&EPCW[divider])[1] & 0x80)) //28 clock
    // if (!(((byte*)&EPCW[divider])[1]<0))               //28 clock
    // if (EPCW[divider] < 0)                             //37 clock
    // if (EPCW[divider] > 0x7FFF)                        //37 clock

    if (((unsigned int*)&EPCW[divider])[0] > 0x7FFF)    //28 clock
      EPCW[divider] = EPCW[divider];
    else
      EPCW[divider] = EPCW[divider];

So a small difference exists using pointer. Seemed the same with word or byte.
So I guess it’s 9 clock cycles faster this way.
The interrupt fires every 800 clocks.