using binary numbers in c

Discussion in 'C Programming' started by Kelvin@!!!, May 6, 2004.

  1. Kelvin@!!!

    Kelvin@!!! Guest

    Hi everyone:
    when we wanna use hex numbers in C, we usually write something like:
    int hex_num = 0x12F9;

    but how can I declare a binary number in a similar way by putting some
    leading words to tell the complier this is a binary number???
    similarly, in printf, we have %d for an decimal number %x and %o for hex and
    octal numbers... how about binary numbers??

    Thank you very much...
    --
    { Kelvin@!!! }
    Kelvin@!!!, May 6, 2004
    #1
    1. Advertising

  2. Kelvin@!!!

    Leor Zolman Guest

    On Thu, 06 May 2004 01:18:56 GMT, "Kelvin@!!!" <>
    wrote:

    >Hi everyone:
    >when we wanna use hex numbers in C, we usually write something like:
    >int hex_num = 0x12F9;
    >
    >but how can I declare a binary number in a similar way by putting some
    >leading words to tell the complier this is a binary number???
    >similarly, in printf, we have %d for an decimal number %x and %o for hex and
    >octal numbers... how about binary numbers??
    >
    >Thank you very much...


    Here's something I picked up from, I believe, this very newsgroup not long
    back:

    ------------- macros.h: ---------------------------------

    /*
    macros.h:
    Binary constant generator macro
    By Tom Torfs - donated to the public domain
    */

    /* All macro's evaluate to compile-time constants */

    /* *** helper macros *** */

    /* turn a numeric literal into a hex constant
    (avoids problems with leading zeroes)
    8-bit constants max value 0x11111111, always fits in unsigned long
    */
    #define HEX__(n) 0x##n##LU

    /* 8-bit conversion function */
    #define B8__(x) ((x&0x0000000FLU)?1:0) \
    +((x&0x000000F0LU)?2:0) \
    +((x&0x00000F00LU)?4:0) \
    +((x&0x0000F000LU)?8:0) \
    +((x&0x000F0000LU)?16:0) \
    +((x&0x00F00000LU)?32:0) \
    +((x&0x0F000000LU)?64:0) \
    +((x&0xF0000000LU)?128:0)

    /* *** user macros *** */

    /* for upto 8-bit binary constants */
    #define B8(d) ((unsigned char)B8__(HEX__(d)))

    /* for upto 16-bit binary constants, MSB first */
    #define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \
    + B8(dlsb))

    /* for upto 32-bit binary constants, MSB first */
    #define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \
    + ((unsigned long)B8(db2)<<16) \
    + ((unsigned long)B8(db3)<<8) \
    + B8(dlsb))

    /* Sample usage:
    B8(01010101) = 85
    B16(10101010,01010101) = 43605
    B32(10000000,11111111,10101010,01010101) = 2164238933
    */

    ------------ test.c ---------------------

    #include <stdio.h>
    #include "macros.h"

    int main()
    {
    int i = B8(1010);
    int j = B8(10000000);

    printf("i = %d, j = %d\n", i, j);
    return 0;
    }


    HTH,
    -leor


    --
    Leor Zolman --- BD Software --- www.bdsoft.com
    On-Site Training in C/C++, Java, Perl and Unix
    C++ users: download BD Software's free STL Error Message Decryptor at:
    www.bdsoft.com/tools/stlfilt.html
    Leor Zolman, May 6, 2004
    #2
    1. Advertising

  3. Kelvin@!!!

    Mike Wahler Guest

    "Kelvin@!!!" <> wrote in message
    news:4ogmc.384222$Ig.25579@pd7tw2no...
    > Hi everyone:
    > when we wanna use hex numbers in C, we usually write something like:
    > int hex_num = 0x12F9;
    >
    > but how can I declare a binary number in a similar way by putting some
    > leading words to tell the complier this is a binary number???


    First let me dispel what I think is an erroneous notion you have.
    All numbers are stored as 'binary'. When you talk about e.g.
    'decimal', 'binary', 'hex', etc., you're talking about the
    *textual* representation of a number, e.g. using digits 0-9,
    0 and 1, 0 - F, etc.

    That said, no, C has no syntax for expressing a binary pattern in source
    code. Hex is as close (and imo more 'convenient') as it gets.

    > similarly, in printf, we have %d for an decimal number %x and %o for hex

    and
    > octal numbers... how about binary numbers??


    Nope, printf() doesn't have a type specifier for "zero and one"
    representation. But it's trivial to write a function
    to produce a string of zero and one characters from an integer,
    then use %s with its output.

    Hints:

    x % 2;
    x /= 2;

    A function could also be written to input a string containing
    zeros and ones and convert it to a numeric type.

    -Mike
    Mike Wahler, May 6, 2004
    #3
  4. Kelvin@!!!

    Kelvin@!!! Guest

    "Leor Zolman" <> wrote in message
    news:...
    > On Thu, 06 May 2004 01:18:56 GMT, "Kelvin@!!!" <>
    > wrote:
    >
    > >Hi everyone:
    > >when we wanna use hex numbers in C, we usually write something like:
    > >int hex_num = 0x12F9;
    > >
    > >but how can I declare a binary number in a similar way by putting some
    > >leading words to tell the complier this is a binary number???
    > >similarly, in printf, we have %d for an decimal number %x and %o for hex

    and
    > >octal numbers... how about binary numbers??
    > >
    > >Thank you very much...

    >
    > Here's something I picked up from, I believe, this very newsgroup not long
    > back:
    >
    > ------------- macros.h: ---------------------------------
    >
    > /*
    > macros.h:
    > Binary constant generator macro
    > By Tom Torfs - donated to the public domain
    > */
    >
    > /* All macro's evaluate to compile-time constants */
    >
    > /* *** helper macros *** */
    >
    > /* turn a numeric literal into a hex constant
    > (avoids problems with leading zeroes)
    > 8-bit constants max value 0x11111111, always fits in unsigned long
    > */
    > #define HEX__(n) 0x##n##LU
    >
    > /* 8-bit conversion function */
    > #define B8__(x) ((x&0x0000000FLU)?1:0) \
    > +((x&0x000000F0LU)?2:0) \
    > +((x&0x00000F00LU)?4:0) \
    > +((x&0x0000F000LU)?8:0) \
    > +((x&0x000F0000LU)?16:0) \
    > +((x&0x00F00000LU)?32:0) \
    > +((x&0x0F000000LU)?64:0) \
    > +((x&0xF0000000LU)?128:0)
    >
    > /* *** user macros *** */
    >
    > /* for upto 8-bit binary constants */
    > #define B8(d) ((unsigned char)B8__(HEX__(d)))
    >
    > /* for upto 16-bit binary constants, MSB first */
    > #define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \
    > + B8(dlsb))
    >
    > /* for upto 32-bit binary constants, MSB first */
    > #define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \
    > + ((unsigned long)B8(db2)<<16) \
    > + ((unsigned long)B8(db3)<<8) \
    > + B8(dlsb))
    >
    > /* Sample usage:
    > B8(01010101) = 85
    > B16(10101010,01010101) = 43605
    > B32(10000000,11111111,10101010,01010101) = 2164238933
    > */
    >
    > ------------ test.c ---------------------
    >
    > #include <stdio.h>
    > #include "macros.h"
    >
    > int main()
    > {
    > int i = B8(1010);
    > int j = B8(10000000);
    >
    > printf("i = %d, j = %d\n", i, j);
    > return 0;
    > }
    >
    >
    > HTH,
    > -leor
    >
    >
    > --
    > Leor Zolman --- BD Software --- www.bdsoft.com
    > On-Site Training in C/C++, Java, Perl and Unix
    > C++ users: download BD Software's free STL Error Message Decryptor at:
    > www.bdsoft.com/tools/stlfilt.html


    thank you for the code...
    but ...
    > #define HEX__(n) 0x##n##LU


    what does the # stands for here???

    --
    { Kelvin@!!! }
    Kelvin@!!!, May 6, 2004
    #4
  5. Kelvin@!!! <> scribbled the following:
    > "Leor Zolman" <> wrote in message
    > news:...
    >> Here's something I picked up from, I believe, this very newsgroup not long
    >> back:


    (snip)

    > thank you for the code...
    > but ...
    >> #define HEX__(n) 0x##n##LU


    > what does the # stands for here???


    Assuming you know what #define means and are asking about the ##:
    It's a preprocessor operator that "glues" two preprocessing tokens into
    one C token. Here it's used twice, gluing three preprocessing tokens
    together. The first is 0x, the second is whatever n gets replaced with,
    and the third is LU. For example HEX__(0) would be expanded to a glued
    together token 0x0LU. The C compiler itself treats this as a single
    token and not as three tokens after each other.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "It sure is cool having money and chicks."
    - Beavis and Butt-head
    Joona I Palaste, May 6, 2004
    #5
  6. Kelvin@!!!

    Mabden Guest

    "Kelvin@!!!" <> wrote in message
    news:4ogmc.384222$Ig.25579@pd7tw2no...
    > Hi everyone:
    > when we wanna use hex numbers in C, we usually write something like:
    > int hex_num = 0x12F9;
    >
    > but how can I declare a binary number in a similar way by putting some
    > leading words to tell the complier this is a binary number???
    > similarly, in printf, we have %d for an decimal number %x and %o for hex

    and
    > octal numbers... how about binary numbers??
    >


    There isn't a way to do that, as the compiler does know from binary.

    OTOH, you could write a pre-processor that does that, if you wish. It would
    take your new symbol, say 0b11110000 and turn it into 0xF0, then pass it
    into the compiler.

    For printf(), you'd have to write a function to change hex to a binary
    string, I surmise. It would have to be at run-time since the variables, are.

    --
    Mabden
    Mabden, May 6, 2004
    #6
  7. http://www.eskimo.com/~scs/C-faq/q20.11.html

    --


    ~Kieran Simkin
    Digital Crocus
    http://digital-crocus.com/

    "Kelvin@!!!" <> wrote in message
    news:4ogmc.384222$Ig.25579@pd7tw2no...
    > Hi everyone:
    > when we wanna use hex numbers in C, we usually write something like:
    > int hex_num = 0x12F9;
    >
    > but how can I declare a binary number in a similar way by putting some
    > leading words to tell the complier this is a binary number???
    > similarly, in printf, we have %d for an decimal number %x and %o for hex

    and
    > octal numbers... how about binary numbers??
    >
    > Thank you very much...
    > --
    > { Kelvin@!!! }
    >
    >
    Kieran Simkin, May 8, 2004
    #7
  8. Kelvin@!!!

    zuger

    Joined:
    Jul 25, 2009
    Messages:
    1
    Nice . . . small changes

    Thank you for the nice example. I changed it slightly to work for my needs in an embedded processor. I type casted with (unsigned long). It seems to work. Why was the 16B type cased differently than the 32B in the original example?


    #define HEX__(n) 0x##n##LU

    /* 8-bit conversion function */
    #define B8__(x) ((x&0x0000000FLU)?1:0) \
    +((x&0x000000F0LU)?2:0) \
    +((x&0x00000F00LU)?4:0) \
    +((x&0x0000F000LU)?8:0) \
    +((x&0x000F0000LU)?16:0) \
    +((x&0x00F00000LU)?32:0) \
    +((x&0x0F000000LU)?64:0) \
    +((x&0xF0000000LU)?128:0)

    /* *** user macros *** */

    /* for upto 8-bit binary constants */
    #define B8(d) ((unsigned char)B8__(HEX__(d)))

    /* for upto 16-bit binary constants, MSB first */
    #define B16(dmsb,dlsb) (((unsigned long)B8(dmsb)<< 8) + (unsigned long)B8(dlsb))


    /* for upto 32-bit binary constants, MSB first */
    #define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \
    + ((unsigned long)B8(db2)<<16) \
    + ((unsigned long)B8(db3)<< 8) \
    + B8(dlsb))

    /* Sample usage:
    B8(01010101) = 85
    B16(10101010,01010101) = 43605
    B32(10000000,11111111,10101010,01010101) = 2164238933
    */
    zuger, Jul 25, 2009
    #8
  9. Kelvin@!!!

    cchris

    Joined:
    Aug 6, 2010
    Messages:
    1
    let compiler detect non binary values

    Thanks for this.
    The code above inspired me to a version that does _not_ compile if non binary values are entered:

    typedef enum
    {
    b0000 = 0x00,
    b0001 = 0x01,
    b0010 = 0x02,
    b0011 = 0x03,
    b0100 = 0x04,
    b0101 = 0x05,
    b0110 = 0x06,
    b0111 = 0x07,
    b1000 = 0x08,
    b1001 = 0x09,
    b1010 = 0x0A,
    b1011 = 0x0B,
    b1100 = 0x0C,
    b1101 = 0x0D,
    b1110 = 0x0E,
    b1111 = 0x0F
    } T_BIN_NIBBLE;

    /* 2 nibbles to 8 bit */
    #define B8(msn,lsn) ( ( b##msn<<4 ) \
    |( b##lsn ) )

    /* 4 nibbles to 16 bit */
    #define B16(msn,n2, n1,lsn) ( (unsigned short)( b##msn<<12 ) \
    |(unsigned short)( b##n2 <<8 ) \
    |(unsigned short)( b##n1 <<4 ) \
    |(unsigned short)( b##lsn ) )

    /* Sample usage:
    B8(0101,0101) = 85
    B16(1010,1010 , 0101,0101) = 43605
    */
    cchris, Aug 6, 2010
    #9
  10. Kelvin@!!!

    rchandelier

    Joined:
    Sep 28, 2011
    Messages:
    1
    A few compilers (usually Microcontroller's ones) has a special feature implemented within recognizing literal binary numbers by prefix "0b..." preceding the number, although most compilers (C/C++ standards) don't have such feature and if it is the case, here it is my alternative solution:

    #define B_0000 0
    #define B_0001 1
    #define B_0010 2
    #define B_0011 3
    #define B_0100 4
    #define B_0101 5
    #define B_0110 6
    #define B_0111 7
    #define B_1000 8
    #define B_1001 9
    #define B_1010 a
    #define B_1011 b
    #define B_1100 c
    #define B_1101 d
    #define B_1110 e
    #define B_1111 f

    #define _B2H(bits) B_##bits
    #define B2H(bits) _B2H(bits)
    #define _HEX(n) 0x##n##UL
    #define HEX(n) _HEX(n)
    #define _CCAT(a,b) a##b
    #define CCAT(a,b) _CCAT(a,b)

    #define BYTE(a,b) HEX( CCAT(B2H( a),B2H( b)) )
    #define WORD(a,b,c,d) HEX( CCAT(CCAT(B2H( a),B2H( b)),CCAT(B2H( c),B2H( d))) )
    #define DWORD(a,b,c,d,e,f,g,h) HEX( CCAT( CCAT(CCAT(B2H( a),B2H( b)),CCAT(B2H( c),B2H( d))),CCAT(CCAT(B2H( e),B2H( f)),CCAT(B2H( g),B2H( h))) ) )

    //using example
    char b = BYTE(0100,0001); //equivalent to b = 65; or b = 'A'; or b = 0x41;
    unsigned int w = WORD(1101,1111,0100,0011); //equivalent to w = 57155; or w = 0xdf43;
    unsigned long int dw = DWORD(1101,1111,0100,0011,1111,1101,0010,1000); //equivalent to dw = 3745774888; or dw = 0xdf43fd28;

    Disadvantages: (it's not such a big ones)
    - The binary numbers have to be grouped 4 by 4;
    - The binary literals have to be only unsigned integer numbers;

    Advantages:
    - Total preprocessor driven, not spending processor time in pointless operations (like "?.. :..", "<<", "+") to the executable program (it may be performed hundred of times in the final application);
    - It works "mainly in C" compilers and C++ as well (template+enum solution works only in C++ compilers);
    - It has only the limitation of "longness" for expressing "literal constant" values. There would have been earlyish longness limitation (usually 8bits:0-255) if one had expressed constant values by parsing resolve of "enum solution"(usually 255 = reach enum definition limit), differently, "literal constant" limitations, in the compiler allows greater numbers;
    - Some other solutions demand exagerated number of constant definitions (#define's in my opinion) including long or several header files (in most cases not easily readable and understandable, and make the project become unnecessarily confused and extended, like that using "BOOST_BINARY()");
    - Simplicity of the solution: easily readable, understandable and adjustable for other cases (could be extended for grouping 8 by 8 too);

    I hope it helps, thanks. Renato Chandelier.

    rchandelier, Sep 28, 2011
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Subra
    Replies:
    25
    Views:
    1,173
    user923005
    Mar 8, 2007
  2. Andrew Tatum

    Fibonacci Numbers and Lucas Numbers

    Andrew Tatum, May 26, 2007, in forum: C++
    Replies:
    6
    Views:
    545
    Howard
    May 27, 2007
  3. Lance Hoffmeyer
    Replies:
    2
    Views:
    513
    Lance Hoffmeyer
    Jul 26, 2007
  4. Kaytiana

    Using Binary numbers to create a matrix

    Kaytiana, Mar 20, 2010, in forum: C Programming
    Replies:
    0
    Views:
    301
    Kaytiana
    Mar 20, 2010
  5. Replies:
    3
    Views:
    420
Loading...

Share This Page