[misc.misc] Printing binary

eric@snark.UUCP (Eric S. Raymond) (10/19/87)

In article <148@artsvax.UUCP>, mike@artsvax.UUCP (Michael Czeiszperger) writes:
> The variable five is certainly stored in binary, even though it represents
> an integer.  A more plausible interpretation in a test situation would be
> to print each of the binary bits out in ascii, so that the output for an 
> integer 5 (assuming a large machine where an integer is 4 bytes) would be:
> 
> 00000000000000000000000000000101

I thought about the standard ways to do this, (essentially, crack the sucker
into powers-of-two internally via repeated integer-divide and modulo
operations) went *ugh*, and then had a flash that gave me an amusing
alternate solution. Here it is: (warning! this is untested and off-the-cuff)

#include "stdio.h"

void bprint(n, fp)
/* print n in binary to given fp */
int	n;
FILE	*fp;
{
    static char *nybbles =
    {
	"0000", "0001", "0010", "0011",	"0100", "0101", "0110", "0111",
	"1000", "1001", "1010", "1011",	"1100", "1101", "1110", "1111",
    };
    static char hexdigits = "0123456789abcdef";

    char foobuf[BUFSIZ], *cp;	/* BUFSIZ from stdio.h */

    (void) sprintf(cp = foobuf, "%x", n);
    while (*cp)
	(void) fputs(nybbles[strchr(hexdigits, *cp++) - hexdigits], fp);
}

Le voila! Let the C libraries do the work whenever you can, I always say...
-- 
      Eric S. Raymond
      UUCP:  {{seismo,ihnp4,rutgers}!cbmvax,sdcrdcf!burdvax,vu-vlsi}!snark!eric
      Post:  22 South Warren Avenue, Malvern, PA 19355    Phone: (215)-296-5718

smvorkoetter@watmum.UUCP (10/20/87)

In article <235@snark.UUCP> eric@snark.UUCP (Eric S. Raymond) writes:
>I thought about the standard ways to do this, (essentially, crack the sucker
>into powers-of-two internally via repeated integer-divide and modulo
>operations) went *ugh*, and then had a flash that gave me an amusing
>alternate solution. Here it is: (warning! this is untested and off-the-cuff)

There is a very quick way to do this using only the <<, >>, and & operators:

#define	BITS		32			/* or 16 */

void print_binary(n)
int n;
{
	int i;

	for(i = 0; i < BITS; i++) {
		printf("%1d",(n >> (BITS - 1)) & 1);
		n <<= 1;
	}
}

bright@dataio.Data-IO.COM (Walter Bright) (10/23/87)

In article <2072@watcgl.waterloo.edu> smvorkoetter@watmum.waterloo.edu (Stefan M. Vorkoetter) writes:
>In article <235@snark.UUCP> eric@snark.UUCP (Eric S. Raymond) writes:
>>I thought about the standard ways to do this, (essentially, crack the sucker
>>into powers-of-two internally via repeated integer-divide and modulo
>>operations) went *ugh*, and then had a flash that gave me an amusing
>>alternate solution. Here it is: (warning! this is untested and off-the-cuff)
>
>There is a very quick way to do this using only the <<, >>, and & operators:
>
>#define	BITS		32			/* or 16 */
>
>void print_binary(n)
>int n;
>{
>	int i;
>
>	for(i = 0; i < BITS; i++) {
>		printf("%1d",(n >> (BITS - 1)) & 1);
>		n <<= 1;
>	}
>}


Newsgroups: misc.misc,comp.lang.c
Subject: Re: Printing binary (was: Re: Why college?)
Summary: 
Expires: 
References: <35@ateng.UUCP> <3194@sol.ARPA> <2783@xanth.UUCP> <235@snark.UUCP> <2072@watcgl.waterloo.edu>
Sender: 
Reply-To: bright@dataio.UUCP (Walter Bright)
Followup-To: 
Distribution: 
Organization: Data I/O Corporation; Redmond, WA
Keywords: 

In article <2072@watcgl.waterloo.edu> smvorkoetter@watmum.waterloo.edu (Stefan M. Vorkoetter) writes:
<In article <235@snark.UUCP< eric@snark.UUCP (Eric S. Raymond) writes:
<<I thought about the standard ways to do this, (essentially, crack the sucker
<<into powers-of-two internally via repeated integer-divide and modulo
<<operations) went *ugh*, and then had a flash that gave me an amusing
<<alternate solution. Here it is: (warning! this is untested and off-the-cuff)
<There is a very quick way to do this using only the <<, >>, and & operators:
<#define	BITS		32			/* or 16 */
<void print_binary(n)
<int n;
<{	int i;
<	for(i = 0; i < BITS; i++) {
<		printf("%1d",(n >> (BITS - 1)) & 1);
<		n <<= 1;
<	}
<}

I simply modified the printf() format to add a %b format specifier for
binary format. It added a case and 1 line of code. Also, things like
%04b were gotten for free. I imagine that this is equally trivial for
other compilers.

Anyone know why ANSI C doesn't specify this? I wrote them a letter which
they haven't replied to.

greg@gryphon.CTS.COM (Greg Laskin) (10/25/87)

In article <2072@watcgl.waterloo.edu> smvorkoetter@watmum.waterloo.edu (Stefan M. Vorkoetter) writes:
>In article <235@snark.UUCP> eric@snark.UUCP (Eric S. Raymond) writes:
>>I thought about the standard ways to do this, (essentially, crack the sucker
>>into powers-of-two internally via repeated integer-divide and modulo
>>operations) went *ugh*, and then had a flash that gave me an amusing
>>alternate solution. Here it is: (warning! this is untested and off-the-cuff)
>
>There is a very quick way to do this using only the <<, >>, and & operators:
>
>#define	BITS		32			/* or 16 */
>
>void print_binary(n)
>int n;
>{
>	int i;
>
>	for(i = 0; i < BITS; i++) {
>		printf("%1d",(n >> (BITS - 1)) & 1);
                              ^^^^^^^^^^^^^^^
			      not a constant expression
>		n <<= 1;
>	}
>}



#define BitsPerUnit 8

void print_binary(n)
	int n;
{
	int i;

	for (i=0; i < (sizeof (int) * BitsPerUnit) ; ++i,n<<=1)
		putchar(( n & (1<<(sizeof (int) * BitsPerUnit) -1)) ? '1' : '0');
			      /*   a constant expression         */
}

Using the constant expression is "quick"er.  On my 16 bit machine, the compiler
can resolve the expression to:
	putchar((n & 0x8000 ) ? '1' : '0');
at compile time instead of shifting n BITS bits BITS times at run time.

Using putchar() instead of printf() is picking a nit.

Comments on portability to other environments solicited (by email please).



-- 
Greg Laskin   
"When everybody's talking and nobody's listening, how can we decide?"
INTERNET:     Greg.Laskin@gryphon.CTS.COM
UUCP:         {hplabs!hp-sdd, sdcsvax, ihnp4}!crash!gryphon!greg
UUCP:         {philabs, scgvaxd}!cadovax!gryphon!greg