Leading 0xFFFFFF when Serial.print(char, HEX) ?

i was wondering why whith the following very basic sketch , i get random leading FFFFFF with some value but not all ??

it have happened to me quite a few time in random projet and i am always in the rabbit hole to figure out why and what is happening

please look at comment in code

Thanks

char TestCharD3 = 0xD3;
char TestChar6A = 0x6A;

void setup() {

Serial.begin(9600);

Serial.println(TestCharD3, HEX);        // print FFFFFFD3

Serial.println((byte)TestCharD3, HEX);  // print D3

Serial.println(TestChar6A, HEX);        // print 6A
                                        // WHY NOT leading FFFFFF with this one

Serial.println((byte)TestChar6A, HEX);  // print 6A

}

void loop() {

}

You get leading FFFFFF with negative numbers. This is because negative numbers are represented by "two's complement" format. Search for this term if you want to know more.

oh i see now

seemed random at first but just made a for loop to observe this

from decimal 0 to 127 no leading FFFFFF

from decimal 128 to 255 leading FFFFFF

will look at "two's complement" format

A bit more details on what happens

A char is a signed type on one byte meaning that from 128 and up to 255 you really have a negative number (-128 to 0).

In the Arduino core, println() comes from the Print class.

When you write something like

Serial.println(x, HEX);

the compiler needs to find which overloaded println function expecting two parameters and there are promotion rules if the type of the parameters do not exactly match. Here is what the compiler had to choose from (Those are declared in Print.h.)

As there is no char type for the first parameter and it’s a signed type, the compiler will try to find the next larger signed type that can accept your char and this is int so it ends up calling

And as so the parameter is now a 16 or 32 bit integral number (depending on your platform) and you has for its hexadecimal representation which does include the FF at the start

@tfoutfou

Check my printHelpers library

It offers different print methods the standard Arduino print does not do, including HEX

For completeness you could retry your code with the variables defined as unsigned char and see what happens.

Why are you using char type for this anyway? You're treating it like an unsigned 8-bit value. So use uint8_t.

Basically when you invert all the bits of a negative number you get what is called a one's complement. The snag with that is it produces two values for zero, in effect a positive zero and a negative zero. The trouble is that mathmatically there is no such thing. So to avoid this problem we add one to the one's complement and call that the two's complement.

Then using this concept gets rid of two codes for zero and produces a much more satisfactory value where normal arithmetic can be used with both positive and negative values with normal arithmetic values.

Hope that helps.

In standard real analysis, there is indeed only one real number 0.

When studying limits, we distinguish approaching from the right (denoted 0+) or from the left (denoted 0-). For example,

lim(x→+∞) 1/x = 0+
lim(x→−∞) 1/x = 0-

So in that sense, 0+ and 0- are not numbers themselves but notations for directional approach toward zero. And computers actually have 0+ and 0- as distinct values in floating-point arithmetic (IEEE-754), which behave differently in division and limits.

Yes but we are not discussing calculas here, it is a simple matter of getting the idea of a two's complement notation make things work with normal arrhythmic operations.

We do not want to go to IEEE-754 or else the whole idea of using normal operations goes out of the window.

Ok I thought it was relevant in the discussion.