home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / lang / c / 16071 < prev    next >
Encoding:
Internet Message Format  |  1992-11-07  |  5.2 KB

  1. 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
  2. From: torek@horse.ee.lbl.gov (Chris Torek)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: How to print an integer as binary?
  5. Date: 6 Nov 1992 11:02:15 GMT
  6. Organization: Lawrence Berkeley Laboratory, Berkeley
  7. Lines: 122
  8. Message-ID: <27265@dog.ee.lbl.gov>
  9. References: <1992Nov4.180622.6568@csd.uwe.ac.uk> <1dbpe8INNcop@frigate.doc.ic.ac.uk>
  10. Reply-To: torek@horse.ee.lbl.gov (Chris Torek)
  11. NNTP-Posting-Host: 128.3.112.15
  12.  
  13. In article <1dbpe8INNcop@frigate.doc.ic.ac.uk> anb@doc.ic.ac.uk
  14. (A N Burton) writes:
  15. >The program appearing below gives three possible [ways to print a value
  16.  in binary]
  17.  
  18. Arthur Rubin has already pointed out that, on some machines, there is a
  19. `most negative' number (e.g., -2147483648) which, when negated,
  20. overflows and remains negative.  Method 1 recurses forever if overflow
  21. is undetected.  Method 2 may or may not work, depending on whether
  22. right shift of negative signed integers is arithmetic or logical.
  23. (ANSI C leaves the effect of such shifts implementation-defined.)
  24.  
  25. Methods 2 and 3 have a more interesting feature.  They perform leading
  26. zero suppression---method 2 must do so since it only terminates when
  27. the value goes to zero---but neither one checks to see if the entire
  28. value is 0.  In this case, method 2 produces no output, but method 3
  29. loops forever!
  30.  
  31. Method 3 also makes the assumption that there are 8 bits per `char'.
  32. This can be fixed easily by using CHAR_BIT from <limits.h>.
  33.  
  34. As a general solution, the following will produce a (signed) value in
  35. any base in [2..36].  The caller must supply a sufficiently-large
  36. buffer; ltostr returns a pointer somewhere into this buffer, or NULL
  37. for overflow or error.
  38.  
  39. The code for the corresponding ultostr() function should be obvious.
  40.  
  41. /*
  42.  * Copyright (c) 1992 The Regents of the University of California.
  43.  * All rights reserved.
  44.  *
  45.  * This software was developed by the Computer Systems Engineering group
  46.  * at Lawrence Berkeley Laboratory.
  47.  *
  48.  * All advertising materials mentioning features or use of this software
  49.  * must display the following acknowledgement:
  50.  *    This product includes software developed by the University of
  51.  *    California, Lawrence Berkeley Laboratories.
  52.  *
  53.  * Redistribution and use in source and binary forms, with or without
  54.  * modification, are permitted provided that the following conditions
  55.  * are met:
  56.  * 1. Redistributions of source code must retain the above copyright
  57.  *    notice, this list of conditions and the following disclaimer.
  58.  * 2. Redistributions in binary form must reproduce the above copyright
  59.  *    notice, this list of conditions and the following disclaimer in the
  60.  *    documentation and/or other materials provided with the distribution.
  61.  * 3. All advertising materials mentioning features or use of this software
  62.  *    must display the following acknowledgement:
  63.  *    This product includes software developed by the University of
  64.  *    California, Berkeley and its contributors.
  65.  * 4. Neither the name of the University nor the names of its contributors
  66.  *    may be used to endorse or promote products derived from this software
  67.  *    without specific prior written permission.
  68.  *
  69.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  70.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  71.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  72.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  73.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  74.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  75.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  76.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  77.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  78.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  79.  * SUCH DAMAGE.
  80.  */
  81.  
  82. /*
  83.  * Convert a value (of type long) to a printable representation.
  84.  */
  85. char *
  86. ltostr(long v, int base, char *buf, int size)
  87. {
  88.     register char *p;
  89.     unsigned long u;
  90.     int neg;
  91.     static const char digits[] = "0123456789abcdefghijklmnopqrstuvwyxz";
  92.  
  93.     /*
  94.      * Verify arguments.  Base must be between 2 and 36 (we do not
  95.      * do unary).  We need at least two characters: the smallest
  96.      * value becomes {'0', '\0'}.
  97.      */
  98.     if (base < 2 || base > 36 || size < 2)
  99.         return (NULL);
  100.  
  101.     /*
  102.      * Build the output backwards in the buffer provided.  Remember
  103.      * whether a leading sign is needed; use unsigned to avoid overflow.
  104.      */
  105.     p = buf + size;
  106.     *--p = '\0';            /* at least 1 byte remains */
  107.     if (v < 0) {
  108.         neg = 1;
  109.         u = -(unsigned long)v;
  110.     } else {
  111.         neg = 0;
  112.         u = v;
  113.     }
  114.     /* Loop invariant: there is always room for another digit. */
  115.     for (;;) {
  116.         *--p = digits[u % base];
  117.         u /= base;
  118.         if (u == 0)        /* done */
  119.             break;
  120.         /* Need another digit... check for buffer overrun. */
  121.         if (p == buf)
  122.             return (NULL);
  123.     }
  124.     if (neg) {
  125.         /* We may have exactly filled the buffer, so check first. */
  126.         if (p == buf)
  127.             return (NULL);
  128.         *--p = '-';
  129.     }
  130.     return (p);
  131. }
  132. -- 
  133. In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 510 486 5427)
  134. Berkeley, CA        Domain:    torek@ee.lbl.gov
  135.