I compiled the following code on the Arduino, and in C++. The values I got when I called the function were different, and I have no clue why.

#include <math.h>
int bitArray[6][24]; //the Array of bits, can only be a 1 or 0
int ex=0; //ex keeps track of the current exponent to use to calculate the decimal value of a binary digit
int decArray[18]; //array to store decimals
int byteToDecimal(int pos, int row) //takes two variables so you can give it an array column and row
{
int numholder=0; //Temporary number for calculations
for(int x=pos; x<pos+8;x++) //pos is used to adjust where we start and stop looking at 1's and 0's in a row
{
if(bitArray[row][x] != 0)//if the row and column is a 1
{
numholder += pow(2, 7-ex);//2^(7-ex), meaning the first bit is worth 2^7, and the last is 2^0
}
ex++;
}
ex=0;
return numholder;
}

Calling the following line

byteToDecimal(0,0)

Returns 127 in Arduino, and 128 in C++. The C++ value was the intended value, and I have no idea why they are different.

master565:
Returns 127 in Arduino, and 128 in C++. The C++ value was the intended value, and I have no idea why they are different.

Arduino uses C++ so that statement doesn't make sense.

The different sizes of the "int" type are the cause. The C++ standard does not mandate that an int is 32 bits. I have also seen that a "long" can be 64 bits, whereas it used to be 32 bits for a lot of CPUs I was working on.

master565:
What does that syntax mean in plain English?

<< is the left shift operator. It shifts the bits in an integer to the left.

1 << 3 means take a 16 bit value of 1 and shift all the bits 3 to the left, shifting 0’s in from the right and shifting the top bits out.

1 << 3 takes
binary 0000000000000001 = decimal 1
and makes it
binary 0000000000001000 = decimal 8
or you could multiply by 2 3 times in a row.

If you don’t know bits, you should. They provide wonderful shortcuts and ways to save memory, sometime LOTS of memory. For example, your code uses an array of 16-bit ints to hold 0 or 1 for each. That’s hugely wasteful considering that an UNO only has 2048 bytes of RAM for everything including the stack, a Leo only has 2560.

My personal view is that knowing what's inside the box and how it works will save confusion and be more use when finding an approach to any given project. Use the bit functions where they suit but know what they do and how the information is arranged and used because there's times when just knowing the minimum won't get you from A to B.

If you don't know about integer variables as bits then you're likely to make an int array to store 0's and 1's.
If you only know there's functions to set and read single bits, you're likely to use those to process that array.

when putting the same 0 or 1 into bits 0 to 3 of a byte lets you do this

if ( var > 0 )
{
// do something
}

If I only want to know about bits 0 and 2 then

byte testbits = bit( 0 ) + bit( 2 );
if (( var & tesbits ) > 0 )
{
// do something
}

In a loop or function, testbits and var can be changing. One piece of code can handle situations where otherwise there would have to be an if() line for every combination of bit checks needed, and we do see that kind of code quite a lot.

When you know bits that can be values and also in a variable, a set of associated true/false data at the same time, you can generalize and reduce your code which reduces debugging. In many cases the savings in time and effort can be great and possibly mean faster running code that fits on smaller, cheaper machines.

That is why I urge beginners and not-so-beginners to learn things like bits and yes, even pointers!