Hi, aren't these types supposed to guarantee their respective sizes? For some reason they are defined and report correct sizes with sizeof() but when used they are 32bit. Hilariously compiler report overflow warnings correctly too
int8_t x = -320;
// warning: overflow in implicit constant conversion [-Woverflow]
int16_t y = -1;
int32_t z = -1;
Serial.println(sizeof(int8_t));
Serial.println(sizeof(int16_t));
Serial.println(sizeof(int32_t));
Serial.println(x, HEX);
Serial.println(y, HEX);
Serial.println(z, HEX);
The source code for the print statements show that the data type printed is long no matter the (numeric) data type printed.
...\Arduino 1.8.19\hardware\arduino\avr\cores\arduino\Print.cpp
size_t Print::print(unsigned char b, int base)
{
return print((unsigned long) b, base);
}
size_t Print::print(int n, int base)
{
return print((long) n, base);
}
You are seeing what the print command does to numbers. There are many questions and dislikes of this feature/bug in the print command especially when printing HEX. The first in the decimal print out are correct. The HEX printouts are correct as the print command defaults to 32 bits on HEX numbers. Try positive numbers for x, y, z. This link may help: sizeof() - Arduino Reference
To my annoyance, (s)printf() doesn't do binary as far as I can see. Would be really useful sometimes to print binary with leading zeros. Certainly more useful than octal, which hasn't been used much since before the time of the "terrible lizards", but you can print octal with leading zeros
For me, it would be useful to print binary with leading zeros when you need a quick easy way to visualise data which is a bitmap rather than numeric data, like a character or symbol to be printed to an LCD/OLED/LED matrix or 7/14 segment display.
I wrote this when I was testing something to do with binary data and saved it as PrintBin.h
It allows binary printing of an integer value of any type with leading zeroes with or without a following linefeed and with the printed values split into bytes or not
Restriction: It only returns the HEX value of the two least significant bytes (even if you change int to long).
"%0.4X" makes sure you get capital letters and it is formatted to four characters with leading zeros
Anyway it should be no big issue to use sizeof() to adopt it to 4 or 8 byte data ...
P.S.: This works (but is probably not the best way to do it ... )
void DecToHex(long Value, int noOfBytes) {
char buf0[5];
char buf1[5];
char format[] = "%0.4X";
if (noOfBytes < 2) {
format[3] = '2';
}
sprintf(buf0, format, Value);
if (noOfBytes > 2) {
sprintf(buf1, format, Value >> 16);
Serial.print(buf1);
}
Serial.println(buf0);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Start");
byte x = 0xFF123456;
DecToHex(x, sizeof(x));
int y = 0xFF123456;
DecToHex(y, sizeof(y));
long z = 0xFF123456;
DecToHex(z, sizeof(z));
}
void loop() {
// put your main code here, to run repeatedly:
}
@groundFungus@UKHeliBob thanks guys, but it wasn't a cry for help, be assured I have my favourite ways of printing the binary data in the way I want, already memorised. My point was it would be great if printf() would just do it, like it does for decimal or hex, so I don't have to do anything. For example
Serial.printf("%08b", myByte);
@ec2021 maybe I confused you somehow, sorry about that. I want printf() in binary. I know it works great in hex.
Serial.printf() isn't available on all cores I thought?
In any event, for printing hex, it's bloated AF. I got so fed up with the lousy output or unacceptable bloat for the insanely common - and also much easier for computers to do than everything else that functions like that output) that my cores have printHex() which does leading zeros - it's a bunch of functions to take different datatypes and then call printHex(uint8_t);, including swapping of bytes to reverse endianness (mainly for applications where you've got bytes-in-order-stored, and you're want to read larger datatypes made up of those - the human brain has the wrong endianness to read them natively). and it can take pointers to easily dump the contents of the whole extended IO block dedicated to a peripheral when debugging. And it's considerably smaller than Serial.print() or Serial.printf().
One could do a similar thing for binary and also be very flash efficient. I basically never want to print binary, so I haven't done it.