Unexpected behaviour of bitwise not on a byte

LS

Bitwise not on a byte with highest bit a 1 behaves in the way I expect.
The inverted byte is 255 minus byte.
I can use it in char = (char)inverted byte and gives me an ascii character.
When I use a byte with highest bit a 0 the inverted byte is also 255 minus byte.
But when I want to use that inverted byte in char = (char)inverted byte I get a negative number.

The output of the sketch that I post here illustrates that.

myByte =: 128
bitwise not myByte is: 127
myChar = (char)temp; is: 127

myByte =: 208
bitwise not myByte is: 47
myChar = (char)temp; is: 47

myByte =: 127
bitwise not myByte is: 128
myChar = (char)temp; is: -128

myByte =: 33
bitwise not myByte is: 222
myChar = (char)temp; is: -34

Maybe I don't understand well enough the idea of typecasting.
Maybe a byte is not always unsigned.
Maybe ...... you know the right answer.

byte myByte;
char myChar;
byte temp;

void setup() {
  Serial.begin(115200);
}

void loop() {
  printMyByte(128); //proces myByte
  printMyByte(208);
  printMyByte(127);
  printMyByte(33);
  
  while (true);//wait for ever
}

void printMyByte( byte myByte) {
  Serial.print("myByte =: ");
  Serial.println(myByte, DEC);
  
  temp = ~myByte;//temp is bitwise not myByte

  Serial.print("bitwise not myByte is: ");
  Serial.println(temp, DEC);

  myChar = (char)temp;//myChar is inverted myByte typecasted as a char

  Serial.print("myChar = (char)temp; is: ");
  Serial.print(myChar, DEC);

  Serial.print("\n\n");

}

Maybe a byte is not always unsigned.

A byte is always unsigned. A char is signed. The range of values for a char is -128 to 127.

A char is signed, a byte is not.
On the right side of an equal sign, variables are converted to 16 bit int (or higher) PRIOR to arithmetic.
Conversion from 16 bits to 8 bits across the equal sign may be a simple truncation.
Think bits, not decimal values.

Thanks for the answers.
When I think in bites I see this:

myByte =: 128
myByte binair =: 10000000
bitwise not myByte is: 127
bitwise not myByte binair =: 1111111
Case 1 myChar = (char)temp; 1111111 decimal: 127

myByte =: 127
myByte binair =: 1111111
bitwise not myByte is: 128
bitwise not myByte binair =: 10000000
Case 2myChar = (char)temp; 11111111111111111111111110000000 decimal: -128

myChar seems to be a 32-bits long .

I do not know what "bites" is. Bits? Bytes?
Why 8 bit quantities went to 7 bits I do not know.
myChar is declared as char and is ALWAYS 8 bits, NEVER 32 bits.

bites are bits for a Dutch. :-}

8 bits doesn't change in 7 bits.
Only the leading zeroes are not printed.

FrenskeP:
bites are bits for a Dutch. :-}

If English isn't your first language, we have a section for the Netherlands

AWOL:
If English isn't your first language, we have a section for the Netherlands

All the Dutch I've ever met speak better English than most folk for whom English is their first language.

@AWOL: Thanks. I think for now I stay here.

@Kenwood120s:

FrenskeP:
@Kenwood120s:

Looks like you hit Post before you finished typing?

My answer was an invisible smiley. :wink:
I have a 5 minutes limit.

Printing a negative value as 32 bits (or 8 nibbles in hex) is an artifact of how the Print object prints a 'char' when you specify a base. There is no "Print::print(char c, int base)" so the 'char' gets promoted to an 'int' (with the requisite sign extension) and the call is made to:

size_t Print::print(int n, int base)
{
  return print((long) n, base);
}

When the 'int' is cast to 'long' the sign extension is extended to 32 bits.
If you cast your char to 'unsigned char' (a.k.a. 'byte') before you print it as binary or hex you will get the proper effect.

What they can add to eliminate this confusing artifact is:

size_t Print::print(char c, int base)
{
  if (base == 10)
    return print((long) c, base);
  else
    return print((unsigned long) (unsigned char) c, base);  // Prevent sign extension for binary and hex
}

and

size_t Print::print(int n, int base)
{
  if (base == 10)
    return print((long) n, base);
  else
    return print((unsigned long) (unsigned int) n, base);  // Prevent sign extension for binary and hex
}

@johnwasser: your answer is very helpfull.
Thanks a lot.