How to print the leading zeroes?

Hi.
In one of my sketches, I want verify a list of results with the statement:

Serial.println(RegInp, BIN);

The variable RegInp is defined with

word RegInp = 0x0000; // where results are stored

My problem is that I desire to have always 16 bit even if the binary number is less than 0x1000000000000000 as to say that I need to see all the bits always aligned in the same column of the screen.
The problem is common in the HEX representation, when a 16bit number is less than 0x8000.

Can someone give me the solution to this problem?
I suppose that in the Arduino C language there is some kind of "formatter" for the output.
Thank you so much.

You can write a function that prints out the format you desire, leading zeros etc.

It would be a good way for you to learn some some programming.

.

The website doesn't need you to print leading zeros.

The forum is not interested in leading zeros, either.

What made you think THIS was an appropriate place to post?

Thank you for the answers.

Maybe "Programming questions" has bring me out of theme.
I'm sorry to have disturbed somebody, posting my silly question in the wrong place.

There are some more complicated formatters that can do that. But it's easier to write a function to do what you want. Just make a loop of 16 and use bitRead() to read every bit :slight_smile:

I thank you really so much.
I had wrote this post because I was thinking that there was some way to do this ready to use.
Some little symbol to switch the output format forcing the full length of a 16 bit binary word as a 4 digit hexadecimal word.
But I'm quite surely wrong.

I surely will write some function to obtain my desired result, but until now I was convinced to be at the begin of the "warm water" invention!
I like spend my time studying useful (more or less) thing, but i try to avoid to re-invent what it's already invented.
Your hint appear to me as a very simple solution and a very good help.
And is meaningless the amount of code, because this my need stand up just during the debug phases, but at the end I will suppress all the Serial.print and the way to format it.
Thank you again.

Try this little goober:

prntBits(RegInp);

void prntBits(int b)
{
  for(int i = 15; i >= 0; i--)
  {
    Serial.print(bitRead(b,i));
    if(i % 4 == 0) Serial.print(" ");
  }  
  Serial.println();
}

I wrote this little piece just yesterday

void printBinWithLeading(Print &out, unsigned long n, byte size){
  for(byte i = size - 1; i--;){
    out.print(bitRead(n, i));
   
    if(i == 0){
      break;
    }
  }
}

inline void printBinWithLeading(Print &out, unsigned long n){
  printBinWithLeading(out, n, sizeof(n) * 8);
}

inline void printBinWithLeading(Print &out, unsigned int n){
  printBinWithLeading(out, n, sizeof(n) * 8);
}

inline void printBinWithLeading(Print &out, byte n){
  printBinWithLeading(out, n, sizeof(n) * 8);
}

First parameter is a Print object. If you want to print it to Serial use it like

printBinWithLeading(Serial, RegInp);

septillion:
I wrote this little piece just yesterday

Templates!!!

template <typename T> T serialPrintBinary(T x, bool usePrefix)
{
  if(usePrefix) Serial.print("0b");
  for(int i = 0; i < 8 * sizeof(x); i++)
  {
    Serial.print(bitRead(x, sizeof(x) * 8 - i - 1));
  }
  Serial.println();
  return x;
}

void setup() 
{
  Serial.begin(9600);
  uint8_t first = 0x0F;
  serialPrintBinary(first, false);
  uint16_t second = 0x0F0F;
  serialPrintBinary(second, false);
  uint32_t last = 0x0F0F0F0F;
  serialPrintBinary(last, true);
}

void loop() 
{

}

Templates!!!

The problem with templates is that they let you do really stupid things, like pass a String to the function. What is bitRead() supposed to do with a String?

And, if you then use it for a byte, a uint and a ulong in the same sketch it will make the function 3 times instead of using one general function... So yeah, thought about templates but those two things combined let me to make a general function and inline helper functions.

PaulS:
The problem with templates is that they let you do really stupid things, like pass a String to the function. What is bitRead() supposed to do with a String?

Well, in thais case it is type safe... bitRead() won't take a String/float/char* as an argument...

your compiler is your friend....

septillion:
And, if you then use it for a byte, a uint and a ulong in the same sketch it will make the function 3 times instead of using one general function...

but yours would create four...

I guess I missed your point

EDIT: I guess inlining them makes them go away....?

But it probably doesn't... three are inline and are short enough so I expect the compiler to indeed inline them. And even if it doesn't, they are a lot smaller then 3 times the main function...

septillion:
And even if it doesn't, they are a lot smaller then 3 times the main function...

I think you are contradicting yourself...

Not if you are using it a lot, and it really inlines them.... you are creating instructions (even if you only work with one type) every time you call that function, No?

If the helper functions are inline (and I see no reason for the compiler not to) then it's always just a call to the same function.

If you make a template it would result in calls to three different functions which are all three nearly identical.

septillion:
If the helper functions are inline (and I see no reason for the compiler not to) then it's always just a call to the same function.

you may be confused regarding the inline keyword.

What is inline function :
The inline functions are a C++ enhancement feature to increase the execution time of a program. Functions can be instructed to compiler to make them inline so that compiler can replace those function definition wherever those are being called. Compiler replaces the definition of inline functions at compile time instead of referring function definition at runtime.
NOTE- This is just a suggestion to compiler to make the function inline, if function is big (in term of executable instruction etc) then, compiler can ignore the “inline” request and treat the function as normal function.

Call your inline function in 20 places, you have ballooned your code (albeit much faster than a function call).

Why will it balloon my code?

If it doesn't inline my code then yes, there are 3 extra functions but they are small. They are just a call to another function. Smaller then having the main function three times in a slightly different way.

And if it does inline it all it does is replacing printBinWithLeading(Serial, RegInp) with printBinWithLeading(Serial, RegInp, 16) leaving only a single function to call.

And if I try my function agains a template:

template <typename T> void printBinWithLeading(Print &out, T n){
    for(byte i = sizeof(n) * 8 - 1; i--;){
    out.print(bitRead(n, i));
   
    if(i == 0){
      break;
    }
  }
}

Then it's 1720bytes for inline and 1792bytes for the template. Which I would expect because if effectively has the same function three times. And if I do call it 20 times on 20 different variables then 2482bytes for the inline and 2602bytes for the template...

So yeah, I want to learn but I can't see how it can balloon my code...

Whole test code:

byte myByte1 = 1;
unsigned int myInt1 = 111;
unsigned long myLong1 = 111111;

byte myByte2 = 2;
unsigned int myInt2 = 222;
unsigned long myLong2 = 222222;

byte myByte3 = 3;
unsigned int myInt3 = 333;
unsigned long myLong3 = 333333;

byte myByte4 = 4;
unsigned int myInt4 = 444;
unsigned long myLong4 = 444444;

byte myByte5 = 5;
unsigned int myInt5 = 555;
unsigned long myLong5 = 555555;

byte myByte6 = 6;
unsigned int myInt6 = 666;
unsigned long myLong6 = 666666;

byte myByte7 = 7;
unsigned int myInt7 = 777;
unsigned long myLong7 = 777777;

byte myByte8 = 8;
unsigned int myInt8 = 888;
unsigned long myLong8 = 888888;

byte myByte9 = 9;
unsigned int myInt9 = 999;
unsigned long myLong9 = 999999;

byte myByte10 = 10;
unsigned int myInt10 = 000;
unsigned long myLong10 = 000000;

byte myByte11 = 11;
unsigned int myInt11 = 111;
unsigned long myLong11 = 111111;

byte myByte12 = 12;
unsigned int myInt12 = 222;
unsigned long myLong12 = 222222;

byte myByte13 = 13;
unsigned int myInt13 = 333;
unsigned long myLong13 = 333333;

byte myByte14 = 14;
unsigned int myInt14 = 444;
unsigned long myLong14 = 444444;

byte myByte15 = 15;
unsigned int myInt15 = 555;
unsigned long myLong15 = 555555;

byte myByte16 = 16;
unsigned int myInt16 = 666;
unsigned long myLong16 = 666666;

byte myByte17 = 17;
unsigned int myInt17 = 777;
unsigned long myLong17 = 777777;

byte myByte18 = 18;
unsigned int myInt18 = 888;
unsigned long myLong18 = 888888;

byte myByte19 = 19;
unsigned int myInt19 = 999;
unsigned long myLong19 = 999999;

byte myByte20 = 20;
unsigned int myInt20 = 000;
unsigned long myLong20 = 000000;


void setup() {
  Serial.begin(115200);
  printBinWithLeading(Serial, myByte1);
  Serial.println();
  printBinWithLeading(Serial, myInt1);
  Serial.println();
  printBinWithLeading(Serial, myLong1);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte2);
  Serial.println();
  printBinWithLeading(Serial, myInt2);
  Serial.println();
  printBinWithLeading(Serial, myLong2);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte3);
  Serial.println();
  printBinWithLeading(Serial, myInt3);
  Serial.println();
  printBinWithLeading(Serial, myLong3);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte4);
  Serial.println();
  printBinWithLeading(Serial, myInt4);
  Serial.println();
  printBinWithLeading(Serial, myLong4);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte5);
  Serial.println();
  printBinWithLeading(Serial, myInt5);
  Serial.println();
  printBinWithLeading(Serial, myLong5);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte6);
  Serial.println();
  printBinWithLeading(Serial, myInt6);
  Serial.println();
  printBinWithLeading(Serial, myLong6);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte7);
  Serial.println();
  printBinWithLeading(Serial, myInt7);
  Serial.println();
  printBinWithLeading(Serial, myLong7);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte8);
  Serial.println();
  printBinWithLeading(Serial, myInt8);
  Serial.println();
  printBinWithLeading(Serial, myLong8);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte9);
  Serial.println();
  printBinWithLeading(Serial, myInt9);
  Serial.println();
  printBinWithLeading(Serial, myLong9);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte10);
  Serial.println();
  printBinWithLeading(Serial, myInt10);
  Serial.println();
  printBinWithLeading(Serial, myLong10);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte11);
  Serial.println();
  printBinWithLeading(Serial, myInt11);
  Serial.println();
  printBinWithLeading(Serial, myLong11);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte12);
  Serial.println();
  printBinWithLeading(Serial, myInt12);
  Serial.println();
  printBinWithLeading(Serial, myLong12);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte13);
  Serial.println();
  printBinWithLeading(Serial, myInt13);
  Serial.println();
  printBinWithLeading(Serial, myLong13);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte14);
  Serial.println();
  printBinWithLeading(Serial, myInt14);
  Serial.println();
  printBinWithLeading(Serial, myLong14);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte15);
  Serial.println();
  printBinWithLeading(Serial, myInt15);
  Serial.println();
  printBinWithLeading(Serial, myLong15);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte16);
  Serial.println();
  printBinWithLeading(Serial, myInt16);
  Serial.println();
  printBinWithLeading(Serial, myLong16);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte17);
  Serial.println();
  printBinWithLeading(Serial, myInt17);
  Serial.println();
  printBinWithLeading(Serial, myLong17);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte18);
  Serial.println();
  printBinWithLeading(Serial, myInt18);
  Serial.println();
  printBinWithLeading(Serial, myLong18);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte19);
  Serial.println();
  printBinWithLeading(Serial, myInt19);
  Serial.println();
  printBinWithLeading(Serial, myLong19);
  Serial.println("\n");
  printBinWithLeading(Serial, myByte20);
  Serial.println();
  printBinWithLeading(Serial, myInt20);
  Serial.println();
  printBinWithLeading(Serial, myLong20);
  Serial.println("\n");
}

void loop() {
  
}


void printBinWithLeading(Print &out, unsigned long n, byte size){
  for(byte i = size - 1; i--;){
    out.print(bitRead(n, i));
   
    if(i == 0){
      break;
    }
  }
}

inline void printBinWithLeading(Print &out, unsigned long n){
  printBinWithLeading(out, n, sizeof(n) * 8);
}

inline void printBinWithLeading(Print &out, unsigned int n){
  printBinWithLeading(out, n, sizeof(n) * 8);
}

inline void printBinWithLeading(Print &out, byte n){
  printBinWithLeading(out, n, sizeof(n) * 8);
}


/*
template <typename T> void printBinWithLeading(Print &out, T n){
    for(byte i = sizeof(n) * 8 - 1; i--;){
    out.print(bitRead(n, i));
   
    if(i == 0){
      break;
    }
  }
}*/

mine (1.8.2) compiles the same size using your function set or your template!!

Sketch uses 2602 bytes (8%) of program storage space.

Stupid compiler....

:wink:

Must say, I was indeed running a different version (1.8.1) but I just downloaded 1.8.2

1.8.1
Inline: 2482bytes
Template: 2602bytes

1.8.2
Inline: 2482bytes
Template: 2602bytes

So same results, template a good 100 bytes bigger....