ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

num_get_float.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */
00018 
00019 #include "stlport_prefix.h"
00020 
00021 #include <limits>
00022 #include <locale>
00023 #include <istream>
00024 
00025 #if (defined (__GNUC__) && !defined (__sun) && !defined (__hpux)) || \
00026     defined (__DMC__)
00027 #  include <stdint.h>
00028 #endif
00029 
00030 #if defined (__linux__) || defined (__MINGW32__) || defined (__CYGWIN__) || \
00031     defined (__BORLANDC__) || defined (__DMC__) || defined (__HP_aCC)
00032 
00033 #  if defined (__BORLANDC__)
00034 typedef unsigned int uint32_t;
00035 typedef unsigned __int64 uint64_t;
00036 #  endif
00037 
00038 union _ll {
00039   uint64_t i64;
00040   struct {
00041 #  if defined (_STLP_BIG_ENDIAN)
00042     uint32_t hi;
00043     uint32_t lo;
00044 #  elif defined (_STLP_LITTLE_ENDIAN)
00045     uint32_t lo;
00046     uint32_t hi;
00047 #  else
00048 #    error Unknown endianess
00049 #  endif
00050   } i32;
00051 };
00052 
00053 #  if defined (__linux__)
00054 #    include <ieee754.h>
00055 #  else
00056 union ieee854_long_double {
00057   long double d;
00058 
00059   /* This is the IEEE 854 double-extended-precision format.  */
00060   struct {
00061     unsigned int mantissa1:32;
00062     unsigned int mantissa0:32;
00063     unsigned int exponent:15;
00064     unsigned int negative:1;
00065     unsigned int empty:16;
00066   } ieee;
00067 };
00068 
00069 #    define IEEE854_LONG_DOUBLE_BIAS 0x3fff
00070 #  endif
00071 #endif
00072 
00073 _STLP_BEGIN_NAMESPACE
00074 _STLP_MOVE_TO_PRIV_NAMESPACE
00075 
00076 //----------------------------------------------------------------------
00077 // num_get
00078 
00079 // Helper functions for _M_do_get_float.
00080 
00081 #if !defined (_STLP_NO_WCHAR_T)
00082 void  _STLP_CALL
00083 _Initialize_get_float( const ctype<wchar_t>& ct,
00084                        wchar_t& Plus, wchar_t& Minus,
00085                        wchar_t& pow_e, wchar_t& pow_E,
00086                        wchar_t* digits) {
00087   char ndigits[11] = "0123456789";
00088   Plus  = ct.widen('+');
00089   Minus = ct.widen('-');
00090   pow_e = ct.widen('e');
00091   pow_E = ct.widen('E');
00092   ct.widen(ndigits + 0, ndigits + 10, digits);
00093 }
00094 #endif /* WCHAR_T */
00095 
00096 /*
00097  * __string_to_double is just lifted from atof, the difference being
00098  * that we just use '.' for the decimal point, rather than let it
00099  * be taken from the current C locale, which of course is not accessible
00100  * to us.
00101  */
00102 #if defined (_STLP_MSVC) || defined (__BORLANDC__) || defined (__ICL)
00103 typedef unsigned long uint32;
00104 typedef unsigned __int64 uint64;
00105 #  define ULL(x) x##Ui64
00106 #elif defined (__unix) || defined (__MINGW32__) || \
00107       (defined (__DMC__) && (__LONGLONG)) || defined (__WATCOMC__)
00108 typedef uint32_t uint32;
00109 typedef uint64_t uint64;
00110 #  define ULL(x) x##ULL
00111 #else
00112 #  error There should be some unsigned 64-bit integer on the system!
00113 #endif
00114 
00115 // Multiplication of two 64-bit integers, giving a 128-bit result.
00116 // Taken from Algorithm M in Knuth section 4.3.1, with the loop
00117 // hand-unrolled.
00118 static void _Stl_mult64(const uint64 u, const uint64 v,
00119                         uint64& high, uint64& low) {
00120   const uint64 low_mask = ULL(0xffffffff);
00121   const uint64 u0 = u & low_mask;
00122   const uint64 u1 = u >> 32;
00123   const uint64 v0 = v & low_mask;
00124   const uint64 v1 = v >> 32;
00125 
00126   uint64 t = u0 * v0;
00127   low = t & low_mask;
00128 
00129   t = u1 * v0 + (t >> 32);
00130   uint64 w1 = t & low_mask;
00131   uint64 w2 = t >> 32;
00132 
00133   uint64 x = u0 * v1 + w1;
00134   low += (x & low_mask) << 32;
00135   high = u1 * v1 + w2 + (x >> 32);
00136 }
00137 
00138 #ifndef __linux__
00139 
00140 #  define bit11 ULL(0x7ff)
00141 #  define exponent_mask (bit11 << 52)
00142 
00143 #  if !defined (__GNUC__) || (__GNUC__ != 3) || (__GNUC_MINOR__ != 4) || \
00144       (!defined (__CYGWIN__) && !defined (__MINGW32__))
00145 //Generate bad code when compiled with -O2 option.
00146 inline
00147 #  endif
00148 void _Stl_set_exponent(uint64 &val, uint64 exp)
00149 { val = (val & ~exponent_mask) | ((exp & bit11) << 52); }
00150 
00151 #endif // __linux__
00152 
00153 /* Power of ten fractions for tenscale*/
00154 /* The constants are factored so that at most two constants
00155  * and two multiplies are needed. Furthermore, one of the constants
00156  * is represented exactly - 10**n where 1<= n <= 27.
00157  */
00158 
00159 static const uint64 _Stl_tenpow[80] = {
00160 ULL(0xa000000000000000), /* _Stl_tenpow[0]=(10**1)/(2**4) */
00161 ULL(0xc800000000000000), /* _Stl_tenpow[1]=(10**2)/(2**7) */
00162 ULL(0xfa00000000000000), /* _Stl_tenpow[2]=(10**3)/(2**10) */
00163 ULL(0x9c40000000000000), /* _Stl_tenpow[3]=(10**4)/(2**14) */
00164 ULL(0xc350000000000000), /* _Stl_tenpow[4]=(10**5)/(2**17) */
00165 ULL(0xf424000000000000), /* _Stl_tenpow[5]=(10**6)/(2**20) */
00166 ULL(0x9896800000000000), /* _Stl_tenpow[6]=(10**7)/(2**24) */
00167 ULL(0xbebc200000000000), /* _Stl_tenpow[7]=(10**8)/(2**27) */
00168 ULL(0xee6b280000000000), /* _Stl_tenpow[8]=(10**9)/(2**30) */
00169 ULL(0x9502f90000000000), /* _Stl_tenpow[9]=(10**10)/(2**34) */
00170 ULL(0xba43b74000000000), /* _Stl_tenpow[10]=(10**11)/(2**37) */
00171 ULL(0xe8d4a51000000000), /* _Stl_tenpow[11]=(10**12)/(2**40) */
00172 ULL(0x9184e72a00000000), /* _Stl_tenpow[12]=(10**13)/(2**44) */
00173 ULL(0xb5e620f480000000), /* _Stl_tenpow[13]=(10**14)/(2**47) */
00174 ULL(0xe35fa931a0000000), /* _Stl_tenpow[14]=(10**15)/(2**50) */
00175 ULL(0x8e1bc9bf04000000), /* _Stl_tenpow[15]=(10**16)/(2**54) */
00176 ULL(0xb1a2bc2ec5000000), /* _Stl_tenpow[16]=(10**17)/(2**57) */
00177 ULL(0xde0b6b3a76400000), /* _Stl_tenpow[17]=(10**18)/(2**60) */
00178 ULL(0x8ac7230489e80000), /* _Stl_tenpow[18]=(10**19)/(2**64) */
00179 ULL(0xad78ebc5ac620000), /* _Stl_tenpow[19]=(10**20)/(2**67) */
00180 ULL(0xd8d726b7177a8000), /* _Stl_tenpow[20]=(10**21)/(2**70) */
00181 ULL(0x878678326eac9000), /* _Stl_tenpow[21]=(10**22)/(2**74) */
00182 ULL(0xa968163f0a57b400), /* _Stl_tenpow[22]=(10**23)/(2**77) */
00183 ULL(0xd3c21bcecceda100), /* _Stl_tenpow[23]=(10**24)/(2**80) */
00184 ULL(0x84595161401484a0), /* _Stl_tenpow[24]=(10**25)/(2**84) */
00185 ULL(0xa56fa5b99019a5c8), /* _Stl_tenpow[25]=(10**26)/(2**87) */
00186 ULL(0xcecb8f27f4200f3a), /* _Stl_tenpow[26]=(10**27)/(2**90) */
00187 
00188 ULL(0xd0cf4b50cfe20766), /* _Stl_tenpow[27]=(10**55)/(2**183) */
00189 ULL(0xd2d80db02aabd62c), /* _Stl_tenpow[28]=(10**83)/(2**276) */
00190 ULL(0xd4e5e2cdc1d1ea96), /* _Stl_tenpow[29]=(10**111)/(2**369) */
00191 ULL(0xd6f8d7509292d603), /* _Stl_tenpow[30]=(10**139)/(2**462) */
00192 ULL(0xd910f7ff28069da4), /* _Stl_tenpow[31]=(10**167)/(2**555) */
00193 ULL(0xdb2e51bfe9d0696a), /* _Stl_tenpow[32]=(10**195)/(2**648) */
00194 ULL(0xdd50f1996b947519), /* _Stl_tenpow[33]=(10**223)/(2**741) */
00195 ULL(0xdf78e4b2bd342cf7), /* _Stl_tenpow[34]=(10**251)/(2**834) */
00196 ULL(0xe1a63853bbd26451), /* _Stl_tenpow[35]=(10**279)/(2**927) */
00197 ULL(0xe3d8f9e563a198e5), /* _Stl_tenpow[36]=(10**307)/(2**1020) */
00198 
00199 // /* _Stl_tenpow[36]=(10**335)/(2**) */
00200 // /* _Stl_tenpow[36]=(10**335)/(2**) */
00201 
00202 ULL(0xfd87b5f28300ca0e), /* _Stl_tenpow[37]=(10**-28)/(2**-93) */
00203 ULL(0xfb158592be068d2f), /* _Stl_tenpow[38]=(10**-56)/(2**-186) */
00204 ULL(0xf8a95fcf88747d94), /* _Stl_tenpow[39]=(10**-84)/(2**-279) */
00205 ULL(0xf64335bcf065d37d), /* _Stl_tenpow[40]=(10**-112)/(2**-372) */
00206 ULL(0xf3e2f893dec3f126), /* _Stl_tenpow[41]=(10**-140)/(2**-465) */
00207 ULL(0xf18899b1bc3f8ca2), /* _Stl_tenpow[42]=(10**-168)/(2**-558) */
00208 ULL(0xef340a98172aace5), /* _Stl_tenpow[43]=(10**-196)/(2**-651) */
00209 ULL(0xece53cec4a314ebe), /* _Stl_tenpow[44]=(10**-224)/(2**-744) */
00210 ULL(0xea9c227723ee8bcb), /* _Stl_tenpow[45]=(10**-252)/(2**-837)     */
00211 ULL(0xe858ad248f5c22ca), /* _Stl_tenpow[46]=(10**-280)/(2**-930) */
00212 ULL(0xe61acf033d1a45df), /* _Stl_tenpow[47]=(10**-308)/(2**-1023)    */
00213 ULL(0xe3e27a444d8d98b8), /* _Stl_tenpow[48]=(10**-336)/(2**-1116) */
00214 ULL(0xe1afa13afbd14d6e)  /* _Stl_tenpow[49]=(10**-364)/(2**-1209) */
00215 };
00216 
00217 static const short _Stl_twoexp[80] = {
00218 4,7,10,14,17,20,24,27,30,34,37,40,44,47,50,54,57,60,64,67,70,74,77,80,84,87,90,
00219 183,276,369,462,555,648,741,834,927,1020,
00220 -93,-186,-279,-372,-465,-558,-651,-744,-837,-930,-1023,-1116,-1209
00221 };
00222 
00223 #define  TEN_1  0           /* offset to 10 **   1 */
00224 #define  TEN_27   26        /* offset to 10 **  27 */
00225 #define  TEN_M28  37        /* offset to 10 ** -28 */
00226 #define  NUM_HI_P 11
00227 #define  NUM_HI_N 13
00228 
00229 #define _Stl_HIBITULL (ULL(1) << 63)
00230 
00231 static void _Stl_norm_and_round(uint64& p, int& norm, uint64 prodhi, uint64 prodlo) {
00232   norm = 0;
00233   if ((prodhi & _Stl_HIBITULL) == 0) {
00234                                 /* leading bit is a zero
00235                                  * may have to normalize
00236                                  */
00237     if ((prodhi == ~_Stl_HIBITULL) &&
00238         ((prodlo >> 62) == 0x3)) {  /* normalization followed by round
00239                                      * would cause carry to create
00240                                      * extra bit, so don't normalize
00241                                      */
00242       p = _Stl_HIBITULL;
00243       return;
00244     }
00245     p = (prodhi << 1) | (prodlo >> 63); /* normalize */
00246     norm = 1;
00247     prodlo <<= 1;
00248   }
00249   else {
00250     p = prodhi;
00251   }
00252 
00253   if ((prodlo & _Stl_HIBITULL) != 0) {     /* first guard bit a one */
00254     if (((p & 0x1) != 0) ||
00255         prodlo != _Stl_HIBITULL ) {    /* not borderline for round to even */
00256       /* round */
00257       ++p;
00258       if (p == 0)
00259         ++p;
00260     }
00261   }
00262 }
00263 
00264 // Convert a 64-bitb fraction * 10^exp to a 64-bit fraction * 2^bexp.
00265 // p:    64-bit fraction
00266 // exp:  base-10 exponent
00267 // bexp: base-2 exponent (output parameter)
00268 static void _Stl_tenscale(uint64& p, int exp, int& bexp) {
00269   bexp = 0;
00270 
00271   if ( exp == 0 ) {              /* no scaling needed */
00272     return;
00273   }
00274 
00275   int exp_hi = 0, exp_lo = exp; /* exp = exp_hi*32 + exp_lo */
00276   int tlo = TEN_1, thi;         /* offsets in power of ten table */
00277   int num_hi;                   /* number of high exponent powers */
00278 
00279   if (exp > 0) {                /* split exponent */
00280     if (exp_lo > 27) {
00281       exp_lo++;
00282       while (exp_lo > 27) {
00283         exp_hi++;
00284         exp_lo -= 28;
00285       }
00286     }
00287     thi = TEN_27;
00288     num_hi = NUM_HI_P;
00289   } else { // exp < 0
00290     while (exp_lo < 0) {
00291       exp_hi++;
00292       exp_lo += 28;
00293     }
00294     thi = TEN_M28;
00295     num_hi = NUM_HI_N;
00296   }
00297 
00298   uint64 prodhi, prodlo;        /* 128b product */
00299   int norm;                     /* number of bits of normalization */
00300 
00301   int hi, lo;                   /* offsets in power of ten table */
00302   while (exp_hi) {              /* scale */
00303     hi = (min) (exp_hi, num_hi);    /* only a few large powers of 10 */
00304     exp_hi -= hi;               /* could iterate in extreme case */
00305     hi += thi-1;
00306     _Stl_mult64(p, _Stl_tenpow[hi], prodhi, prodlo);
00307     _Stl_norm_and_round(p, norm, prodhi, prodlo);
00308     bexp += _Stl_twoexp[hi] - norm;
00309   }
00310 
00311   if (exp_lo) {
00312     lo = tlo + exp_lo -1;
00313     _Stl_mult64(p, _Stl_tenpow[lo], prodhi, prodlo);
00314     _Stl_norm_and_round(p, norm, prodhi, prodlo);
00315     bexp += _Stl_twoexp[lo] - norm;
00316   }
00317 
00318   return;
00319 }
00320 
00321 // First argument is a buffer of values from 0 to 9, NOT ascii.
00322 // Second argument is number of digits in buffer, 1 <= digits <= 17.
00323 // Third argument is base-10 exponent.
00324 
00325 /* IEEE representation */
00326 #if !defined (__linux__)
00327 
00328 union _Double_rep {
00329   uint64 ival;
00330   double val;
00331 };
00332 
00333 static double _Stl_atod(char *buffer, ptrdiff_t ndigit, int dexp) {
00334   typedef numeric_limits<double> limits;
00335   _Double_rep drep;
00336   uint64 &value = drep.ival;  /* Value develops as follows:
00337                                  * 1) decimal digits as an integer
00338                                  * 2) left adjusted fraction
00339                                  * 3) right adjusted fraction
00340                                  * 4) exponent and fraction
00341                                  */
00342 
00343   uint32 guard;         /* First guard bit */
00344   uint64 rest;          /* Remaining guard bits */
00345 
00346   int bexp;             /* binary exponent */
00347   int nzero;            /* number of non-zero bits */
00348   int sexp;             /* scaling exponent */
00349 
00350   char *bufferend;              /* pointer to char after last digit */
00351 
00352   /* Convert the decimal digits to a binary integer. */
00353   bufferend = buffer + ndigit;
00354   value = 0;
00355 
00356   while (buffer < bufferend) {
00357     value *= 10;
00358     value += *buffer++;
00359   }
00360 
00361   /* Check for zero and treat it as a special case */
00362   if (value == 0) {
00363     return 0.0;
00364   }
00365 
00366   /* Normalize value */
00367   bexp = 64;                    /* convert from 64b int to fraction */
00368 
00369   /* Count number of non-zeroes in value */
00370   nzero = 0;
00371   if ((value >> 32) != 0) { nzero  = 32; }    //*TY 03/25/2000 - added explicit comparison to zero to avoid uint64 to bool conversion operator
00372   if ((value >> (16 + nzero)) != 0) { nzero += 16; }
00373   if ((value >> ( 8 + nzero)) != 0) { nzero +=  8; }
00374   if ((value >> ( 4 + nzero)) != 0) { nzero +=  4; }
00375   if ((value >> ( 2 + nzero)) != 0) { nzero +=  2; }
00376   if ((value >> ( 1 + nzero)) != 0) { nzero +=  1; }
00377   if ((value >> (     nzero)) != 0) { nzero +=  1; }
00378 
00379   /* Normalize */
00380   value <<= /*(uint64)*/ (64 - nzero);    //*TY 03/25/2000 - removed extraneous cast to uint64
00381   bexp -= 64 - nzero;
00382 
00383   /* At this point we have a 64b fraction and a binary exponent
00384    * but have yet to incorporate the decimal exponent.
00385    */
00386 
00387   /* multiply by 10^dexp */
00388   _Stl_tenscale(value, dexp, sexp);
00389   bexp += sexp;
00390 
00391   if (bexp <= -1022) {          /* HI denorm or underflow */
00392     bexp += 1022;
00393     if (bexp < -53) {          /* guaranteed underflow */
00394       value = 0;
00395     }
00396     else {                      /* denorm or possible underflow */
00397       int lead0 = 12 - bexp;          /* 12 sign and exponent bits */
00398 
00399       /* we must special case right shifts of more than 63 */
00400       if (lead0 > 64) {
00401         rest = value;
00402         guard = 0;
00403         value = 0;
00404       }
00405       else if (lead0 == 64) {
00406         rest = value & ((ULL(1)<< 63)-1);
00407         guard = (uint32) ((value>> 63) & 1 );
00408         value = 0;
00409       }
00410       else {
00411         rest = value & (((ULL(1) << lead0)-1)-1);
00412         guard = (uint32) (((value>> lead0)-1) & 1);
00413         value >>= /*(uint64)*/ lead0; /* exponent is zero */
00414       }
00415 
00416       /* Round */
00417       if (guard && ((value & 1) || rest) ) {
00418         ++value;
00419         if (value == (ULL(1) << (limits::digits - 1))) { /* carry created normal number */
00420           value = 0;
00421           _Stl_set_exponent(value, 1);
00422         }
00423       }
00424     }
00425   }
00426   else {                        /* not zero or denorm */
00427     /* Round to 53 bits */
00428     rest = value & ((1 << 10) - 1);
00429     value >>= 10;
00430     guard = (uint32) value & 1;
00431     value >>= 1;
00432 
00433     /*  value&1 guard   rest    Action
00434      *
00435      *  dc      0       dc      none
00436      *  1       1       dc      round
00437      *  0       1       0       none
00438      *  0       1       !=0     round
00439      */
00440     if (guard) {
00441       if (((value&1)!=0) || (rest!=0)) {
00442         ++value;                        /* round */
00443         if ((value >> 53) != 0) {       /* carry all the way across */
00444           value >>= 1;          /* renormalize */
00445           ++bexp;
00446         }
00447       }
00448     }
00449     /*
00450      * Check for overflow
00451      * IEEE Double Precision Format
00452      * (From Table 7-8 of Kane and Heinrich)
00453      *
00454      * Fraction bits               52
00455      * Emax                     +1023
00456      * Emin                     -1022
00457      * Exponent bias            +1023
00458      * Exponent bits               11
00459      * Integer bit             hidden
00460      * Total width in bits         64
00461      */
00462 
00463     if (bexp > limits::max_exponent) {          /* overflow */
00464       return limits::infinity();
00465     }
00466     else {                      /* value is normal */
00467       value &= ~(ULL(1) << (limits::digits - 1));   /* hide hidden bit */
00468       _Stl_set_exponent(value, bexp + 1022); /* add bias */
00469     }
00470   }
00471 
00472   _STLP_STATIC_ASSERT(sizeof(uint64) >= sizeof(double))
00473   return drep.val;
00474 }
00475 
00476 #endif
00477 
00478 #if defined (__linux__) || defined (__MINGW32__) || defined (__CYGWIN__) || \
00479     defined (__BORLANDC__) || defined (__DMC__) || defined (__HP_aCC)
00480 
00481 template <class D, class IEEE, int M, int BIAS>
00482 D _Stl_atodT(char *buffer, ptrdiff_t ndigit, int dexp)
00483 {
00484   typedef numeric_limits<D> limits;
00485 
00486   /* Convert the decimal digits to a binary integer. */
00487   char *bufferend = buffer + ndigit; /* pointer to char after last digit */
00488   _ll vv;
00489   vv.i64 = 0L;
00490 
00491   while ( buffer < bufferend ) {
00492     vv.i64 *= 10;
00493     vv.i64 += *buffer++;
00494   }
00495 
00496   if ( vv.i64 == ULL(0) ) { /* Check for zero and treat it as a special case */
00497     return D(0.0);
00498   }
00499 
00500   /* Normalize value */
00501 
00502   int bexp = 64; /* convert from 64b int to fraction */
00503 
00504   /* Count number of non-zeroes in value */
00505   int nzero = 0;
00506   if ((vv.i64 >> 32) != 0) { nzero = 32; }
00507   if ((vv.i64 >> (16 + nzero)) != 0) { nzero += 16; }
00508   if ((vv.i64 >> ( 8 + nzero)) != 0) { nzero +=  8; }
00509   if ((vv.i64 >> ( 4 + nzero)) != 0) { nzero +=  4; }
00510   if ((vv.i64 >> ( 2 + nzero)) != 0) { nzero +=  2; }
00511   if ((vv.i64 >> ( 1 + nzero)) != 0) { nzero +=  1; }
00512   if ((vv.i64 >> (     nzero)) != 0) { nzero +=  1; }
00513 
00514   /* Normalize */
00515   nzero = 64 - nzero;
00516   vv.i64 <<= nzero;    // * TY 03/25/2000 - removed extraneous cast to uint64
00517   bexp -= nzero;
00518 
00519   /* At this point we have a 64b fraction and a binary exponent
00520    * but have yet to incorporate the decimal exponent.
00521    */
00522 
00523   /* multiply by 10^dexp */
00524   int sexp;
00525   _Stl_tenscale(vv.i64, dexp, sexp);
00526   bexp += sexp;
00527 
00528   if ( bexp >= limits::min_exponent ) { /* not zero or denorm */
00529     if ( limits::digits < 64 ) {
00530       /* Round to (64 - M + 1) bits */
00531       uint64_t rest = vv.i64 & ((~ULL(0) / ULL(2)) >> (limits::digits - 1));
00532       vv.i64 >>= M - 2;
00533       uint32_t guard = (uint32) vv.i64 & 1;
00534       vv.i64 >>= 1;
00535 
00536       /*  value&1 guard   rest    Action
00537        *
00538        *  dc      0       dc      none
00539        *  1       1       dc      round
00540        *  0       1       0       none
00541        *  0       1       !=0     round
00542        */
00543 
00544       if (guard) {
00545         if ( ((vv.i64 & 1) != 0) || (rest != 0) ) {
00546           vv.i64++;       /* round */
00547           if ( (vv.i64 >> (limits::digits < 64 ? limits::digits : 0)) != 0 ) { /* carry all the way across */
00548             vv.i64 >>= 1; /* renormalize */
00549             ++bexp;
00550           }
00551         }
00552       }
00553 
00554       vv.i64 &= ~(ULL(1) << (limits::digits - 1)); /* hide hidden bit */
00555     }
00556     /*
00557      * Check for overflow
00558      * IEEE Double Precision Format
00559      * (From Table 7-8 of Kane and Heinrich)
00560      *
00561      * Fraction bits               52
00562      * Emax                     +1023
00563      * Emin                     -1022
00564      * Exponent bias            +1023
00565      * Exponent bits               11
00566      * Integer bit             hidden
00567      * Total width in bits         64
00568      */
00569 
00570     if (bexp > limits::max_exponent) { /* overflow */
00571       return limits::infinity();
00572     }
00573 
00574     /* value is normal */
00575 
00576     IEEE v;
00577 
00578     v.ieee.mantissa0 = vv.i32.hi;
00579     v.ieee.mantissa1 = vv.i32.lo;
00580     v.ieee.negative = 0;
00581     v.ieee.exponent = bexp + BIAS - 1;
00582 
00583     return v.d;
00584   }
00585 
00586   /* HI denorm or underflow */
00587   bexp += BIAS - 1;
00588   if (bexp < -limits::digits) { /* guaranteed underflow */
00589     vv.i64 = 0;
00590   } else {  /* denorm or possible underflow */
00591 
00592     /*
00593      * Problem point for long double: looks like this code reflect shareing of mantissa
00594      * and exponent in 64b int; not so for long double
00595      */
00596 
00597     int lead0 = M - bexp; /* M = 12 sign and exponent bits */
00598     uint64_t rest;
00599     uint32_t guard;
00600 
00601     /* we must special case right shifts of more than 63 */
00602 
00603     if (lead0 > 64) {
00604       rest = vv.i64;
00605       guard = 0;
00606       vv.i64 = 0;
00607     } else if (lead0 == 64) {
00608       rest = vv.i64 & ((ULL(1) << 63)-1);
00609       guard = (uint32) ((vv.i64 >> 63) & 1 );
00610       vv.i64 = 0;
00611     } else {
00612       rest = vv.i64 & (((ULL(1) << lead0)-1)-1);
00613       guard = (uint32) (((vv.i64 >> lead0)-1) & 1);
00614       vv.i64 >>= /*(uint64)*/ lead0; /* exponent is zero */
00615     }
00616 
00617     /* Round */
00618     if (guard && ( (vv.i64 & 1) || rest)) {
00619       vv.i64++;
00620       if (vv.i64 == (ULL(1) << (limits::digits - 1))) { /* carry created normal number */
00621         IEEE v;
00622 
00623         v.ieee.mantissa0 = 0;
00624         v.ieee.mantissa1 = 0;
00625         v.ieee.negative = 0;
00626         v.ieee.exponent = 1;
00627         return v.d;
00628       }
00629     }
00630   }
00631 
00632   IEEE v;
00633 
00634   v.ieee.mantissa0 = vv.i32.hi;
00635   v.ieee.mantissa1 = vv.i32.lo;
00636   v.ieee.negative = 0;
00637   v.ieee.exponent = 0;
00638 
00639   return v.d;
00640 }
00641 #endif // __linux__
00642 
00643 #ifndef __linux__
00644 static double _Stl_string_to_double(const char *s) {
00645   typedef numeric_limits<double> limits;
00646   const int max_digits = limits::digits10 + 2;
00647   unsigned c;
00648   unsigned Negate, decimal_point;
00649   char *d;
00650   int exp;
00651   int dpchar;
00652   char digits[max_digits];
00653 
00654   c = *s++;
00655 
00656   /* process sign */
00657   Negate = 0;
00658   if (c == '+') {
00659     c = *s++;
00660   } else if (c == '-') {
00661     Negate = 1;
00662     c = *s++;
00663   }
00664 
00665   d = digits;
00666   dpchar = '.' - '0';
00667   decimal_point = 0;
00668   exp = 0;
00669 
00670   for (;;) {
00671     c -= '0';
00672     if (c < 10) {
00673       if (d == digits + max_digits) {
00674         /* ignore more than max_digits digits, but adjust exponent */
00675         exp += (decimal_point ^ 1);
00676       } else {
00677         if (c == 0 && d == digits) {
00678           /* ignore leading zeros */
00679         } else {
00680           *d++ = (char) c;
00681         }
00682         exp -= decimal_point;
00683       }
00684     } else if (c == (unsigned int) dpchar && !decimal_point) { /* INTERNATIONAL */
00685       decimal_point = 1;
00686     } else {
00687       break;
00688     }
00689     c = *s++;
00690   }
00691 
00692   /* strtod cant return until it finds the end of the exponent */
00693   if (d == digits) {
00694     return 0.0;
00695   }
00696 
00697   if (c == 'e' - '0' || c == 'E' - '0') {
00698     register unsigned negate_exp = 0;
00699     register int e = 0;
00700     c = *s++;
00701     if (c == '+' || c == ' ') {
00702       c = *s++;
00703     } else if (c == '-') {
00704       negate_exp = 1;
00705       c = *s++;
00706     }
00707     if (c -= '0', c < 10) {
00708       do {
00709         e = e * 10 + (int)c;
00710         c = *s++;
00711       } while (c -= '0', c < 10);
00712 
00713       if (negate_exp) {
00714         e = -e;
00715       }
00716       exp += e;
00717     }
00718   }
00719 
00720   double x;
00721   ptrdiff_t n = d - digits;
00722   if ((exp + n - 1) < limits::min_exponent10) {
00723     x = 0;
00724   }
00725   else if ((exp + n - 1) > limits::max_exponent10) {
00726     x = limits::infinity();
00727   }
00728   else {
00729     /* Let _Stl_atod diagnose under- and over-flows.
00730      * If the input was == 0.0, we have already returned,
00731      * so retval of +-Inf signals OVERFLOW, 0.0 UNDERFLOW */
00732     x = _Stl_atod(digits, n, exp);
00733   }
00734 
00735   if (Negate) {
00736     x = -x;
00737   }
00738 
00739   return x;
00740 }
00741 
00742 #endif
00743 
00744 #if defined (__linux__) || defined (__MINGW32__) || defined (__CYGWIN__) || \
00745     defined (__BORLANDC__) || defined (__DMC__) || defined (__HP_aCC)
00746 
00747 template <class D, class IEEE, int M, int BIAS>
00748 D _Stl_string_to_doubleT(const char *s)
00749 {
00750   typedef numeric_limits<D> limits;
00751   const int max_digits = limits::digits10; /* + 2 17 */;
00752   unsigned c;
00753   unsigned decimal_point;
00754   char *d;
00755   int exp;
00756   D x;
00757   int dpchar;
00758   char digits[max_digits];
00759 
00760   c = *s++;
00761 
00762   /* process sign */
00763   bool Negate = false;
00764   if (c == '+') {
00765     c = *s++;
00766   } else if (c == '-') {
00767     Negate = true;
00768     c = *s++;
00769   }
00770 
00771   d = digits;
00772   dpchar = '.' - '0';
00773   decimal_point = 0;
00774   exp = 0;
00775 
00776   for (;;) {
00777     c -= '0';
00778     if (c < 10) {
00779       if (d == digits + max_digits) {
00780         /* ignore more than max_digits digits, but adjust exponent */
00781         exp += (decimal_point ^ 1);
00782       } else {
00783         if (c == 0 && d == digits) {
00784           /* ignore leading zeros */
00785         } else {
00786           *d++ = (char) c;
00787         }
00788         exp -= decimal_point;
00789       }
00790     } else if (c == (unsigned int) dpchar && !decimal_point) {    /* INTERNATIONAL */
00791       decimal_point = 1;
00792     } else {
00793       break;
00794     }
00795     c = *s++;
00796   }
00797   /* strtod cant return until it finds the end of the exponent */
00798   if (d == digits) {
00799     return D(0.0);
00800   }
00801 
00802   if (c == 'e'-'0' || c == 'E'-'0') {
00803     bool negate_exp = false;
00804     register int e = 0;
00805     c = *s++;
00806     if (c == '+' || c == ' ') {
00807       c = *s++;
00808     } else if (c == '-') {
00809       negate_exp = true;
00810       c = *s++;
00811     }
00812     if (c -= '0', c < 10) {
00813       do {
00814         e = e * 10 + (int)c;
00815         c = *s++;
00816       } while (c -= '0', c < 10);
00817 
00818       if (negate_exp) {
00819         e = -e;
00820       }
00821       exp += e;
00822     }
00823   }
00824 
00825   ptrdiff_t n = d - digits;
00826   if ((exp + n - 1) < limits::min_exponent10) {
00827     return D(0.0); // +0.0 is the same as -0.0
00828   } else if ((exp + n - 1) > limits::max_exponent10 ) {
00829     // not good, because of x = -x below; this may lead to portability problems
00830     x = limits::infinity();
00831   } else {
00832     /* let _Stl_atod diagnose under- and over-flows */
00833     /* if the input was == 0.0, we have already returned,
00834        so retval of +-Inf signals OVERFLOW, 0.0 UNDERFLOW
00835     */
00836     x = _Stl_atodT<D,IEEE,M,BIAS>(digits, n, exp);
00837   }
00838 
00839   return Negate ? -x : x;
00840 }
00841 
00842 #endif // __linux__
00843 
00844 void _STLP_CALL
00845 __string_to_float(const __iostring& v, float& val)
00846 {
00847 #if !defined (__linux__)
00848   val = (float)_Stl_string_to_double(v.c_str());
00849 #else
00850   val = (float)_Stl_string_to_doubleT<double,ieee754_double,12,IEEE754_DOUBLE_BIAS>(v.c_str());
00851 #endif
00852 }
00853 
00854 void _STLP_CALL
00855 __string_to_float(const __iostring& v, double& val)
00856 {
00857 #if !defined (__linux__)
00858   val = _Stl_string_to_double(v.c_str());
00859 #else
00860   val = _Stl_string_to_doubleT<double,ieee754_double,12,IEEE754_DOUBLE_BIAS>(v.c_str());
00861 #endif
00862 }
00863 
00864 #if !defined (_STLP_NO_LONG_DOUBLE)
00865 void _STLP_CALL
00866 __string_to_float(const __iostring& v, long double& val) {
00867 #if !defined (__linux__) && !defined (__MINGW32__) && !defined (__CYGWIN__) && \
00868     !defined (__BORLANDC__) && !defined (__DMC__) && !defined (__HP_aCC)
00869   //The following function is valid only if long double is an alias for double.
00870   _STLP_STATIC_ASSERT( sizeof(long double) <= sizeof(double) )
00871   val = _Stl_string_to_double(v.c_str());
00872 #else
00873   val = _Stl_string_to_doubleT<long double,ieee854_long_double,16,IEEE854_LONG_DOUBLE_BIAS>(v.c_str());
00874 #endif
00875 }
00876 #endif
00877 
00878 _STLP_MOVE_TO_STD_NAMESPACE
00879 _STLP_END_NAMESPACE
00880 
00881 // Local Variables:
00882 // mode:C++
00883 // End:

Generated on Sun May 27 2012 04:35:13 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.