what is going on here?
Let us re-write the program of OP as follows for the shake of clarity (not executable):
byte ascii2num(char c)
{
// wandelt eine Hexadezimalzahl in die entspr. Dezimalzahl um
if (isdigit(c))
return(byte(c)-48);
else
return(byte(c)-55);
}
void setup()
{
1. Serial.begin(19200);
2.
3. Serial.println(F("sketch_testDecod"));
4. Serial.print("F=");
5. Serial.print(ascii2num('F')); // test ascii2num()
6. Serial.print(" 5=");
7. Serial.println(ascii2num('5'));
8.
9. Serial.print(ascii2num('F')<<4); //
10. Serial.print("+");
11. Serial.print(ascii2num('A'));
12. Serial.print("=");
13.
14. Serial.print(ascii2num('F')<<4 + ascii2num('A'));
15. Serial.print("=");
16. Serial.println((ascii2num('F')<<4) + ascii2num('A'));
}
a. The ascii2num() function is returning 8-bit unsigned value (byte) to the calling program.
b. In Line-9, we are receiving 15 (00001111). When it is shifted to the left by 4-bit, we get 1111000, which is still of type byte. So, the print function prints a positive value of 240 (F0h = 15x16 + 0x0 = 240).
c. In Line-14, all the mysteries are happening; Post#1 has briefly exposed it; we will dig a little bit deeper here. We are expecting that the print function will show 245760; but it is showing -16384. How?
(1) ascii2num('A') returns +10 (00001010). // byte x1 = 0x0A; 8-bit
(2) ascii2num('F') returns +15 (00001111) // byte x2 = 0x0F; 8-bit
(3) number of shifts to be made to the left = x1 + 4 = 14
(4) If doing by manual calculation, we expect that x2 will take the following bit pattern after being shifted to the left by 14-bit:
0000 1111 00 0000 0000 0000 = (unsigned) 3C000h = 245760.
(5) The value in Step-(4) is 18-bit (forget the leading 0s). The compiler chooses an identifier (x3) of 32-bit wide of type long and not unsigned long to hold the value. Now, it is the hardware circuit of the processor (or the compiler I am not sure) populates the upper 16-bit of x3 with the sign bit (1) of the lower 16-bit of x3.
Now, long x3 = 0b1111 1111 1111 1111 1100 0000 0000 0000 (0xFFFFC000).
The print function, for good reason, treats x3 as signed number, and it prints:
-16384 (-1x215 + 1x214 + 0 + ... + 0 = -32768 + 16384 = -16384).
(6) We may view Line-14 as follows:
byte x1 = ascii2num('A'); // x1 = 0x0A
byte x2 = ascii2num('F'); // x2 = 0x0F
x1 = x1 + 4; // x1 = 14
long x3 = x2 << x1; // x3 = 1111 1111 1111 1111 1100 0000 0000 0000 (sign bit extended)
//casted to an signed int. as has been told in Post#1).
Serial.println(x3); //prints: -16384