Home | History | Annotate | Download | only in gdtoa
      1 /* $NetBSD: smisc.c,v 1.2.14.1 2008/04/08 21:10:55 jdc Exp $ */
      2 
      3 /****************************************************************
      4 
      5 The author of this software is David M. Gay.
      6 
      7 Copyright (C) 1998, 1999 by Lucent Technologies
      8 All Rights Reserved
      9 
     10 Permission to use, copy, modify, and distribute this software and
     11 its documentation for any purpose and without fee is hereby
     12 granted, provided that the above copyright notice appear in all
     13 copies and that both that the copyright notice and this
     14 permission notice and warranty disclaimer appear in supporting
     15 documentation, and that the name of Lucent or any of its entities
     16 not be used in advertising or publicity pertaining to
     17 distribution of the software without specific, written prior
     18 permission.
     19 
     20 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     21 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
     22 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
     23 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     24 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
     25 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
     26 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
     27 THIS SOFTWARE.
     28 
     29 ****************************************************************/
     30 
     31 /* Please send bug reports to David M. Gay (dmg at acm dot org,
     32  * with " at " changed at "@" and " dot " changed to ".").  */
     33 #include  <LibConfig.h>
     34 
     35 #include "gdtoaimp.h"
     36 
     37 #if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */
     38 // Disable: warning C4700: uninitialized local variable 'xx' used
     39 #pragma warning ( disable : 4700 )
     40 #endif  /* defined(_MSC_VER) */
     41 
     42 Bigint *
     43 s2b
     44 #ifdef KR_headers
     45   (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
     46 #else
     47   (CONST char *s, int nd0, int nd, ULong y9)
     48 #endif
     49 {
     50   Bigint *b;
     51   int i, k;
     52   Long x, y;
     53 
     54   x = (nd + 8) / 9;
     55   for(k = 0, y = 1; x > y; y <<= 1, k++) ;
     56 #ifdef Pack_32
     57   b = Balloc(k);
     58   if (b == NULL)
     59     return NULL;
     60   b->x[0] = y9;
     61   b->wds = 1;
     62 #else
     63   b = Balloc(k+1);
     64   if (b == NULL)
     65     return NULL;
     66   b->x[0] = y9 & 0xffff;
     67   b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
     68 #endif
     69 
     70   i = 9;
     71   if (9 < nd0) {
     72     s += 9;
     73     do  {
     74       b = multadd(b, 10, *s++ - '0');
     75       if (b == NULL)
     76         return NULL;
     77       } while(++i < nd0);
     78     s++;
     79     }
     80   else
     81     s += 10;
     82   for(; i < nd; i++) {
     83     b = multadd(b, 10, *s++ - '0');
     84     if (b == NULL)
     85       return NULL;
     86     }
     87   return b;
     88   }
     89 
     90  double
     91 ratio
     92 #ifdef KR_headers
     93   (a, b) Bigint *a, *b;
     94 #else
     95   (Bigint *a, Bigint *b)
     96 #endif
     97 {
     98   double da, db;
     99   int k, ka, kb;
    100 
    101   dval(da) = b2d(a, &ka);
    102   dval(db) = b2d(b, &kb);
    103   k = ka - kb + ULbits*(a->wds - b->wds);
    104 #ifdef IBM
    105   if (k > 0) {
    106     word0(da) += (k >> 2)*Exp_msk1;
    107     if (k &= 3)
    108       dval(da) *= 1 << k;
    109     }
    110   else {
    111     k = -k;
    112     word0(db) += (k >> 2)*Exp_msk1;
    113     if (k &= 3)
    114       dval(db) *= 1 << k;
    115     }
    116 #else
    117   if (k > 0)
    118     word0(da) += k*Exp_msk1;
    119   else {
    120     k = -k;
    121     word0(db) += k*Exp_msk1;
    122     }
    123 #endif
    124   return dval(da) / dval(db);
    125   }
    126 
    127 #ifdef INFNAN_CHECK
    128 
    129  int
    130 match
    131 #ifdef KR_headers
    132   (sp, t) CONST char **sp, *t;
    133 #else
    134   (CONST char **sp, CONST char *t)
    135 #endif
    136 {
    137   int c, d;
    138   CONST char *s = *sp;
    139 
    140   while( (d = *t++) !=0) {
    141     if ((c = *++s) >= 'A' && c <= 'Z')
    142       c += 'a' - 'A';
    143     if (c != d)
    144       return 0;
    145     }
    146   *sp = s + 1;
    147   return 1;
    148   }
    149 #endif /* INFNAN_CHECK */
    150 
    151  void
    152 #ifdef KR_headers
    153 copybits(c, n, b) ULong *c; int n; Bigint *b;
    154 #else
    155 copybits(ULong *c, int n, Bigint *b)
    156 #endif
    157 {
    158   ULong *ce, *x, *xe;
    159 #ifdef Pack_16
    160   int nw, nw1;
    161 #endif
    162 
    163   ce = c + ((unsigned int)(n-1) >> kshift) + 1;
    164   x = b->x;
    165 #ifdef Pack_32
    166   xe = x + b->wds;
    167   while(x < xe)
    168     *c++ = *x++;
    169 #else
    170   nw = b->wds;
    171   nw1 = nw & 1;
    172   for(xe = x + (nw - nw1); x < xe; x += 2)
    173     Storeinc(c, x[1], x[0]);
    174   if (nw1)
    175     *c++ = *x;
    176 #endif
    177   while(c < ce)
    178     *c++ = 0;
    179   }
    180 
    181  ULong
    182 #ifdef KR_headers
    183 any_on(b, k) Bigint *b; int k;
    184 #else
    185 any_on(Bigint *b, int k)
    186 #endif
    187 {
    188   int n, nwds;
    189   ULong *x, *x0, x1, x2;
    190 
    191   x = b->x;
    192   nwds = b->wds;
    193   n = (unsigned int)k >> kshift;
    194   if (n > nwds)
    195     n = nwds;
    196   else if (n < nwds && (k &= kmask)) {
    197     x1 = x2 = x[n];
    198     x1 >>= k;
    199     x1 <<= k;
    200     if (x1 != x2)
    201       return 1;
    202     }
    203   x0 = x;
    204   x += n;
    205   while(x > x0)
    206     if (*--x)
    207       return 1;
    208   return 0;
    209   }
    210