home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!europa.asd.contel.com!emory!sol.ctr.columbia.edu!zaphod.mps.ohio-state.edu!saimiri.primate.wisc.edu!ames!agate!dog.ee.lbl.gov!horse.ee.lbl.gov!torek
- From: torek@horse.ee.lbl.gov (Chris Torek)
- Newsgroups: comp.lang.c
- Subject: Re: How to print an integer as binary?
- Date: 6 Nov 1992 11:02:15 GMT
- Organization: Lawrence Berkeley Laboratory, Berkeley
- Lines: 122
- Message-ID: <27265@dog.ee.lbl.gov>
- References: <1992Nov4.180622.6568@csd.uwe.ac.uk> <1dbpe8INNcop@frigate.doc.ic.ac.uk>
- Reply-To: torek@horse.ee.lbl.gov (Chris Torek)
- NNTP-Posting-Host: 128.3.112.15
-
- In article <1dbpe8INNcop@frigate.doc.ic.ac.uk> anb@doc.ic.ac.uk
- (A N Burton) writes:
- >The program appearing below gives three possible [ways to print a value
- in binary]
-
- Arthur Rubin has already pointed out that, on some machines, there is a
- `most negative' number (e.g., -2147483648) which, when negated,
- overflows and remains negative. Method 1 recurses forever if overflow
- is undetected. Method 2 may or may not work, depending on whether
- right shift of negative signed integers is arithmetic or logical.
- (ANSI C leaves the effect of such shifts implementation-defined.)
-
- Methods 2 and 3 have a more interesting feature. They perform leading
- zero suppression---method 2 must do so since it only terminates when
- the value goes to zero---but neither one checks to see if the entire
- value is 0. In this case, method 2 produces no output, but method 3
- loops forever!
-
- Method 3 also makes the assumption that there are 8 bits per `char'.
- This can be fixed easily by using CHAR_BIT from <limits.h>.
-
- As a general solution, the following will produce a (signed) value in
- any base in [2..36]. The caller must supply a sufficiently-large
- buffer; ltostr returns a pointer somewhere into this buffer, or NULL
- for overflow or error.
-
- The code for the corresponding ultostr() function should be obvious.
-
- /*
- * Copyright (c) 1992 The Regents of the University of California.
- * All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratories.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
- /*
- * Convert a value (of type long) to a printable representation.
- */
- char *
- ltostr(long v, int base, char *buf, int size)
- {
- register char *p;
- unsigned long u;
- int neg;
- static const char digits[] = "0123456789abcdefghijklmnopqrstuvwyxz";
-
- /*
- * Verify arguments. Base must be between 2 and 36 (we do not
- * do unary). We need at least two characters: the smallest
- * value becomes {'0', '\0'}.
- */
- if (base < 2 || base > 36 || size < 2)
- return (NULL);
-
- /*
- * Build the output backwards in the buffer provided. Remember
- * whether a leading sign is needed; use unsigned to avoid overflow.
- */
- p = buf + size;
- *--p = '\0'; /* at least 1 byte remains */
- if (v < 0) {
- neg = 1;
- u = -(unsigned long)v;
- } else {
- neg = 0;
- u = v;
- }
- /* Loop invariant: there is always room for another digit. */
- for (;;) {
- *--p = digits[u % base];
- u /= base;
- if (u == 0) /* done */
- break;
- /* Need another digit... check for buffer overrun. */
- if (p == buf)
- return (NULL);
- }
- if (neg) {
- /* We may have exactly filled the buffer, so check first. */
- if (p == buf)
- return (NULL);
- *--p = '-';
- }
- return (p);
- }
- --
- In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 510 486 5427)
- Berkeley, CA Domain: torek@ee.lbl.gov
-