strtoll.c
上传用户:shenzhenrh
上传日期:2013-05-12
资源大小:2904k
文件大小:4k
源码类别:

信息检索与抽取

开发平台:

Unix_Linux

  1. /*-
  2.  * Copyright (c) 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  * This product includes software developed by the University of
  16.  * California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33. /* modified for long long <mgd@swarm.org> 1999-08-12 */
  34. #include <misc.h>
  35. /*
  36.  * Convert a string to a long integer.
  37.  *
  38.  * Ignores `locale' stuff.  Assumes that the upper and lower case
  39.  * alphabets and digits are each contiguous.
  40.  */
  41. long long
  42. strtoll (const char *nptr, char **endptr, int base)
  43. {
  44.   register const char *s = nptr;
  45.   register unsigned long long acc;
  46.   register int c;
  47.   register unsigned long long cutoff;
  48.   register int neg = 0, any, cutlim;
  49.   
  50.   /*
  51.    * Skip white space and pick up leading +/- sign if any.
  52.    * If base is 0, allow 0x for hex and 0 for octal, else
  53.    * assume decimal; if base is already 16, allow 0x.
  54.    */
  55.   do
  56.     {
  57.       c = *s++;
  58.     } while (isSpace(c));
  59.   if (c == '-')
  60.     {
  61.       neg = 1;
  62.       c = *s++;
  63.     }
  64.   else if (c == '+')
  65.     c = *s++;
  66.   if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X'))
  67.     {
  68.       c = s[1];
  69.       s += 2;
  70.       base = 16;
  71.     }
  72.   if (base == 0)
  73.     base = c == '0' ? 8 : 10;
  74.   
  75.   /*
  76.    * Compute the cutoff value between legal numbers and illegal
  77.    * numbers.  That is the largest legal value, divided by the
  78.    * base.  An input number that is greater than this value, if
  79.    * followed by a legal input character, is too big.  One that
  80.    * is equal to this value may be valid or not; the limit
  81.    * between valid and invalid numbers is then based on the last
  82.    * digit.  For instance, if the range for longs is
  83.    * [-2147483648..2147483647] and the input base is 10,
  84.    * cutoff will be set to 214748364 and cutlim to either
  85.    * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
  86.    * a value > 214748364, or equal but the next digit is > 7 (or 8),
  87.    * the number is too big, and we will return a range error.
  88.    *
  89.    * Set any if any `digits' consumed; make it negative to indicate
  90.    * overflow.
  91.    */
  92.   cutoff = neg ? -(unsigned long long) LLONG_MIN : LLONG_MAX;
  93.   cutlim = cutoff % (unsigned long long) base;
  94.   cutoff /= (unsigned long long) base;
  95.   for (acc = 0, any = 0;; c = *s++)
  96.     {
  97.       if (isDigit(c))
  98.         c -= '0';
  99.       else if (isAlpha(c))
  100.         c -= isUpper(c) ? 'A' - 10 : 'a' - 10;
  101.       else
  102.         break;
  103.       if (c >= base)
  104.         break;
  105.       if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
  106.         any = -1;
  107.       else
  108.         {
  109.           any = 1;
  110.           acc *= base;
  111.           acc += c;
  112.         }
  113.     }
  114.   if (any < 0)
  115.     {
  116.       acc = neg ? LLONG_MIN : LLONG_MAX;
  117.       errno = ERANGE;
  118.     }
  119.   else if (neg)
  120.     acc = -acc;
  121.   if (endptr != 0)
  122.     *endptr = (char *) (any ? s - 1 : nptr);
  123.   return acc;
  124. }