Int to Binary

airpanther

Active member
Hi All,

I'm looking for a simple way to convert an integer to a binary number and store it in 1's and 0's. The code below does exactly what I need... it converts 8200 to 10000000001000, but doesn't store it. How can I do the same thing... convert any integer to its binary equivalent and store it in a variable?

Thanks,
Robert

Code:
void setup() {
  Serial.begin(9600);
}

void loop() {
 uint16_t Value = 8200;
 Serial.println(Value,BIN);
 delay(1000);
}
 
I'm not sure I understand you correctly since an integer is stored binary into memory.
But perhaps you mean that you want to store "10000000001000" as a character string?
You can use the itoa function.
Here is the code that prints out "10000000001000" twice.
Code:
char binstring[17];

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

void loop() {
  uint16_t Value = 8200;
  Serial.println(Value, BIN);
  
  itoa(Value, binstring, 2);
  Serial.println(binstring);
  
  delay(1000);
}

Paul
 
Had the same question on phrasing: Suppose it is wanted stored as a series of bits in an array of some sort?

Of course sprintf doesn't do binary - forgot itoa while deciding to play

Here's the fun with itoa error checking:
Code:
uint32_t Value = 18200 * 8191;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial && millis() < 4000 );
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
}

uint32_t cErr = 0;
void loop() {
  // Print Test Reference Strings
  Serial.print(Value, BIN);
  Serial.print("\t0x");
  Serial.print(Value, HEX);
  Serial.print("\t");
  Serial.println(Value);


  // ---- for uints up to 32 bits
  char szBits[33];
  int ii = 32;
  szBits[32] = 0;
  szBits[31] = '0';
  uint32_t tVal = Value;
  while (tVal != 0) {
    szBits[--ii] = (tVal % 2) ? '1' : '0';
    tVal /= 2;
  }
  // Bits in 'Value' are szBits[ii] until NULL==[ii]
  Serial.println( &szBits[ii] ); // Result is a printable C string

  char szComp[33];
  itoa( Value, szComp, 2 );
  if ( 0 != strcmp( szComp, &szBits[ii]) ) {
    Serial.print("\t ERROR \n");
    cErr++;
    delay(2000);
  }

  Serial.print("\t -------------\n");
  delay(1);
  if ( Value > 8191 ) {
    Value -= 8191;
  }
  else {
    Serial.print("\t ERRORS #");
    Serial.print(cErr);
    while (1);
  }
}
 
Yep, that works too.
Code:
void setup() {
  Serial.begin(9600);
}

void loop() {
  uint16_t Value = 8200;
  Serial.println(Value, BIN);
  
  String BinaryString = String(Value, BIN);
  Serial.println(BinaryString);
  
  delay(1000);
}
Just curious: is there an advantage in using the String object over a character array like in my example? Or is it more 'professional' programming?

Paul
 
Yep, that works too.
Code:
void setup() {
  Serial.begin(9600);
}

void loop() {
  uint16_t Value = 8200;
  Serial.println(Value, BIN);
  
  String BinaryString = String(Value, BIN);
  Serial.println(BinaryString);
  
  delay(1000);
}
Just curious: is there an advantage in using the String object over a character array like in my example? Or is it more 'professional' programming?

Paul

By association the String object is then non-pro...
 
Big thanks for the responses!

Code:
String BinaryString = String(Value, BIN);

@Saibot - This worked, thank you! However, when I wanted to invert the binary bits using the ~ operator, the sketch hangs. Makes sense, since ~ is bitwise. The one's and zero's are important to me because each bit represents a physical switch position. Without inverting the bits, all the leading zeros get dropped.

Code:
itoa(~Value, binstring, 2);

@PaulS and @Defragster, thanks much; This worked great! @Paul, to answer your question. The char[] method actually worked better because the ~ operator was able to invert each bit, which I need to be able to do.

Many thanks to each of you!
Robert
 
Had the same question on phrasing: Suppose it is wanted stored as a series of bits in an array of some sort?

If you just wanted the value as a sequence of bits, the C/C++ method is to do shifting and masking. There are two ways to number the bits. The first method is big endian where bit #0 is the sign bit, and in a 32-bit variable, the bit that gives whether it is even/odd is bit 31. The second method is little endian, where bit #31 is the sign bit and bit #0 is the even/odd bit.

Code:
inline int get_bit_big_endian (uint32_t number, int bit_position)
{
  const int bit_adjust = 32 - bit_position - 1;
  return ((number >> bit_adjust) & 1);
}

inline uint32_t clear_bit_big_endian (uint32_t number, int bit_position)
{
  const int bit_adjust = 32 - bit_position - 1;
  return number & ~(((uint32_t)1) << bit_adjust);
}

inline uint32_t set_bit_big_endian (uint32_t number, int bit_position, uint32_t  value = 1)
{
  const int bit_adjust = 32 - bit_position - 1;
  return clear_bit_big_endian (number, bit_position) | ((value & 1) << bit_adjust);
}

inline int get_bit_little_endian (uint32_t number, int bit_position)
{
  return ((number >> bit_position) & 1);
}

inline uint32_t clear_bit_little_endian (uint32_t number, int bit_position)
{
  return number & ~(((uint32_t)1) << bit_position);
}

inline uint32_t set_bit_little_endian (uint32_t number, int bit_position, uint32_t value = 1)
{
  return clear_bit_little_endian (number, bit_position) | ((value & 1) << bit_position);
}

void setup ()
{
  uint32_t five = 0b101;
  Serial.printf ("get_be (0x%08x, 0)    = 0x%08x, get_be (0x%08x, 31)    = 0x%08x\n",
                      (unsigned) five,
	              (unsigned) get_bit_big_endian (five, 0),
	              (unsigned) five,
	              (unsigned) get_bit_big_endian (five, 31));

  Serial.printf ("get_le (0x%08x, 0)    = 0x%08x, get_le (0x%08x, 31)    = 0x%08x\n",
	               (unsigned) five,
	               (unsigned) get_bit_little_endian (five, 0),
	               (unsigned) five,
	               (unsigned) get_bit_little_endian (five, 31));

  Serial.printf ("set_be (0x%08x, 0, 1) = 0x%08x, set_be (0x%08x, 31, 1) = 0x%08x\n",
	               (unsigned) five,
	               (unsigned) set_bit_big_endian (five, 0, 1),
	               (unsigned) five,
	               (unsigned) set_bit_big_endian (five, 31, 1));

  Serial.printf ("set_be (0x%08x, 0, 0) = 0x%08x, set_be (0x%08x, 31, 0) = 0x%08x\n",
	              (unsigned) five,
	              (unsigned) set_bit_big_endian (five, 0, 0),
	              (unsigned) five,
	              (unsigned) set_bit_big_endian (five, 31, 0));

  Serial.printf ("set_le (0x%08x, 0, 1) = 0x%08x, set_le (0x%08x, 31, 1) = 0x%08x\n",
	              (unsigned) five,
	              (unsigned) set_bit_little_endian (five, 0, 1),
	              (unsigned) five,
	              (unsigned) set_bit_little_endian (five, 31, 1));

  Serial.printf ("set_le (0x%08x, 0, 0) = 0x%08x, set_le (0x%08x, 31, 0) = 0x%08x\n",
	              (unsigned) five,
	              (unsigned) set_bit_little_endian (five, 0, 0),
	              (unsigned) five,
	              (unsigned) set_bit_little_endian (five, 31, 0));
}

void loop ()
{
}

Would print:

Code:
get_be (0x00000005, 0)    = 0x00000000, get_be (0x00000005, 31)    = 0x00000001
get_le (0x00000005, 0)    = 0x00000001, get_le (0x00000005, 31)    = 0x00000000
set_be (0x00000005, 0, 1) = 0x80000005, set_be (0x00000005, 31, 1) = 0x00000005
set_be (0x00000005, 0, 0) = 0x00000005, set_be (0x00000005, 31, 0) = 0x00000004
set_le (0x00000005, 0, 1) = 0x00000005, set_le (0x00000005, 31, 1) = 0x80000005
set_le (0x00000005, 0, 0) = 0x00000004, set_le (0x00000005, 31, 0) = 0x00000005

Note, I ran this on my laptop that I post from, and then adjusted it for running on a Teensy.
 
Last edited:
There are probably 100 ways to do this:
It also depends for example on if you wish for example for the string generated to be fixed length like 16 bytes or do you want leading 0's to be removed.

Here is simple brute force way to do it for fixed length output:
Code:
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  while (!Serial && millis() < 10000 );
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  char str[17];
  uint16_t value = 8200;
  Serial.println(value, BIN);
  U16ToB(value, str);
  Serial.println(str);
}

void loop() {
  delay(1000);
  digitalToggleFast( LED_BUILTIN );
}

void U16ToB(uint16_t val, char *str){
  uint16_t mask = 1 << 15;
  while (mask) {
    *str++ = (val & mask)? '1' : '0';
    mask >>= 1;
  }
  *str = '\0';  
}
 
Back
Top