Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Int to Binary

  1. #1
    Junior Member
    Join Date
    Aug 2018
    Posts
    9

    Int to Binary

    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);
    }

  2. #2
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    863
    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

  3. #3
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    16,358
    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);
      }
    }

  4. #4
    Member
    Join Date
    Feb 2020
    Location
    South Africa
    Posts
    46
    Code:
    String BinaryString = String(Value, BIN);

  5. #5
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    863
    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

  6. #6
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    864
    Yuk, Strings stay away from them.

  7. #7
    Member
    Join Date
    Feb 2020
    Location
    South Africa
    Posts
    46
    Quote Originally Posted by PaulS View Post
    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...

  8. #8
    Junior Member
    Join Date
    Aug 2018
    Posts
    9
    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

  9. #9
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    4,271

    Cool

    Quote Originally Posted by defragster View Post
    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 by MichaelMeissner; 08-14-2022 at 07:21 PM.

  10. #10
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    10,948
    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';  
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •