Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright (c) 1999 |
michael@0 | 3 | * Silicon Graphics Computer Systems, Inc. |
michael@0 | 4 | * |
michael@0 | 5 | * Copyright (c) 1999 |
michael@0 | 6 | * Boris Fomitchev |
michael@0 | 7 | * |
michael@0 | 8 | * This material is provided "as is", with absolutely no warranty expressed |
michael@0 | 9 | * or implied. Any use is at your own risk. |
michael@0 | 10 | * |
michael@0 | 11 | * Permission to use or copy this software for any purpose is hereby granted |
michael@0 | 12 | * without fee, provided the above notices are retained on all copies. |
michael@0 | 13 | * Permission to modify the code and to distribute modified code is granted, |
michael@0 | 14 | * provided the above notices are retained, and a notice that the code was |
michael@0 | 15 | * modified is included with the above copyright notice. |
michael@0 | 16 | * |
michael@0 | 17 | */ |
michael@0 | 18 | |
michael@0 | 19 | #include "stlport_prefix.h" |
michael@0 | 20 | |
michael@0 | 21 | #include <limits> |
michael@0 | 22 | #include <locale> |
michael@0 | 23 | #include <istream> |
michael@0 | 24 | |
michael@0 | 25 | #if (defined (__GNUC__) && !defined (__sun) && !defined (__hpux)) || \ |
michael@0 | 26 | defined (__DMC__) |
michael@0 | 27 | # include <stdint.h> |
michael@0 | 28 | #endif |
michael@0 | 29 | |
michael@0 | 30 | #if defined (__linux__) || defined (__MINGW32__) || defined (__CYGWIN__) || \ |
michael@0 | 31 | defined (__BORLANDC__) || defined (__DMC__) || defined (__HP_aCC) |
michael@0 | 32 | |
michael@0 | 33 | # if defined (__BORLANDC__) |
michael@0 | 34 | typedef unsigned int uint32_t; |
michael@0 | 35 | typedef unsigned __int64 uint64_t; |
michael@0 | 36 | # endif |
michael@0 | 37 | |
michael@0 | 38 | union _ll { |
michael@0 | 39 | uint64_t i64; |
michael@0 | 40 | struct { |
michael@0 | 41 | # if defined (_STLP_BIG_ENDIAN) |
michael@0 | 42 | uint32_t hi; |
michael@0 | 43 | uint32_t lo; |
michael@0 | 44 | # elif defined (_STLP_LITTLE_ENDIAN) |
michael@0 | 45 | uint32_t lo; |
michael@0 | 46 | uint32_t hi; |
michael@0 | 47 | # else |
michael@0 | 48 | # error Unknown endianess |
michael@0 | 49 | # endif |
michael@0 | 50 | } i32; |
michael@0 | 51 | }; |
michael@0 | 52 | |
michael@0 | 53 | # if defined (__linux__) && !defined (__ANDROID__) |
michael@0 | 54 | # include <ieee754.h> |
michael@0 | 55 | # else |
michael@0 | 56 | union ieee854_long_double { |
michael@0 | 57 | long double d; |
michael@0 | 58 | |
michael@0 | 59 | /* This is the IEEE 854 double-extended-precision format. */ |
michael@0 | 60 | struct { |
michael@0 | 61 | unsigned int mantissa1:32; |
michael@0 | 62 | unsigned int mantissa0:32; |
michael@0 | 63 | unsigned int exponent:15; |
michael@0 | 64 | unsigned int negative:1; |
michael@0 | 65 | unsigned int empty:16; |
michael@0 | 66 | } ieee; |
michael@0 | 67 | }; |
michael@0 | 68 | |
michael@0 | 69 | # define IEEE854_LONG_DOUBLE_BIAS 0x3fff |
michael@0 | 70 | # endif |
michael@0 | 71 | #endif |
michael@0 | 72 | |
michael@0 | 73 | _STLP_BEGIN_NAMESPACE |
michael@0 | 74 | _STLP_MOVE_TO_PRIV_NAMESPACE |
michael@0 | 75 | |
michael@0 | 76 | //---------------------------------------------------------------------- |
michael@0 | 77 | // num_get |
michael@0 | 78 | |
michael@0 | 79 | // Helper functions for _M_do_get_float. |
michael@0 | 80 | |
michael@0 | 81 | #if !defined (_STLP_NO_WCHAR_T) |
michael@0 | 82 | void _STLP_CALL |
michael@0 | 83 | _Initialize_get_float( const ctype<wchar_t>& ct, |
michael@0 | 84 | wchar_t& Plus, wchar_t& Minus, |
michael@0 | 85 | wchar_t& pow_e, wchar_t& pow_E, |
michael@0 | 86 | wchar_t* digits) { |
michael@0 | 87 | char ndigits[11] = "0123456789"; |
michael@0 | 88 | Plus = ct.widen('+'); |
michael@0 | 89 | Minus = ct.widen('-'); |
michael@0 | 90 | pow_e = ct.widen('e'); |
michael@0 | 91 | pow_E = ct.widen('E'); |
michael@0 | 92 | ct.widen(ndigits + 0, ndigits + 10, digits); |
michael@0 | 93 | } |
michael@0 | 94 | #endif /* WCHAR_T */ |
michael@0 | 95 | |
michael@0 | 96 | /* |
michael@0 | 97 | * __string_to_double is just lifted from atof, the difference being |
michael@0 | 98 | * that we just use '.' for the decimal point, rather than let it |
michael@0 | 99 | * be taken from the current C locale, which of course is not accessible |
michael@0 | 100 | * to us. |
michael@0 | 101 | */ |
michael@0 | 102 | #if defined (_STLP_MSVC) || defined (__BORLANDC__) || defined (__ICL) |
michael@0 | 103 | typedef unsigned long uint32; |
michael@0 | 104 | typedef unsigned __int64 uint64; |
michael@0 | 105 | # define ULL(x) x##Ui64 |
michael@0 | 106 | #elif defined (__unix) || defined (__MINGW32__) || \ |
michael@0 | 107 | (defined (__DMC__) && (__LONGLONG)) || defined (__WATCOMC__) || \ |
michael@0 | 108 | defined (__ANDROID__) |
michael@0 | 109 | typedef uint32_t uint32; |
michael@0 | 110 | typedef uint64_t uint64; |
michael@0 | 111 | # define ULL(x) x##ULL |
michael@0 | 112 | #else |
michael@0 | 113 | # error There should be some unsigned 64-bit integer on the system! |
michael@0 | 114 | #endif |
michael@0 | 115 | |
michael@0 | 116 | // Multiplication of two 64-bit integers, giving a 128-bit result. |
michael@0 | 117 | // Taken from Algorithm M in Knuth section 4.3.1, with the loop |
michael@0 | 118 | // hand-unrolled. |
michael@0 | 119 | static void _Stl_mult64(const uint64 u, const uint64 v, |
michael@0 | 120 | uint64& high, uint64& low) { |
michael@0 | 121 | const uint64 low_mask = ULL(0xffffffff); |
michael@0 | 122 | const uint64 u0 = u & low_mask; |
michael@0 | 123 | const uint64 u1 = u >> 32; |
michael@0 | 124 | const uint64 v0 = v & low_mask; |
michael@0 | 125 | const uint64 v1 = v >> 32; |
michael@0 | 126 | |
michael@0 | 127 | uint64 t = u0 * v0; |
michael@0 | 128 | low = t & low_mask; |
michael@0 | 129 | |
michael@0 | 130 | t = u1 * v0 + (t >> 32); |
michael@0 | 131 | uint64 w1 = t & low_mask; |
michael@0 | 132 | uint64 w2 = t >> 32; |
michael@0 | 133 | |
michael@0 | 134 | uint64 x = u0 * v1 + w1; |
michael@0 | 135 | low += (x & low_mask) << 32; |
michael@0 | 136 | high = u1 * v1 + w2 + (x >> 32); |
michael@0 | 137 | } |
michael@0 | 138 | |
michael@0 | 139 | #if !defined (__linux__) || defined (__ANDROID__) |
michael@0 | 140 | |
michael@0 | 141 | # define bit11 ULL(0x7ff) |
michael@0 | 142 | # define exponent_mask (bit11 << 52) |
michael@0 | 143 | |
michael@0 | 144 | # if !defined (__GNUC__) || (__GNUC__ != 3) || (__GNUC_MINOR__ != 4) || \ |
michael@0 | 145 | (!defined (__CYGWIN__) && !defined (__MINGW32__)) |
michael@0 | 146 | //Generate bad code when compiled with -O2 option. |
michael@0 | 147 | inline |
michael@0 | 148 | # endif |
michael@0 | 149 | void _Stl_set_exponent(uint64 &val, uint64 exp) |
michael@0 | 150 | { val = (val & ~exponent_mask) | ((exp & bit11) << 52); } |
michael@0 | 151 | |
michael@0 | 152 | #endif // __linux__ |
michael@0 | 153 | |
michael@0 | 154 | /* Power of ten fractions for tenscale*/ |
michael@0 | 155 | /* The constants are factored so that at most two constants |
michael@0 | 156 | * and two multiplies are needed. Furthermore, one of the constants |
michael@0 | 157 | * is represented exactly - 10**n where 1<= n <= 27. |
michael@0 | 158 | */ |
michael@0 | 159 | |
michael@0 | 160 | static const uint64 _Stl_tenpow[80] = { |
michael@0 | 161 | ULL(0xa000000000000000), /* _Stl_tenpow[0]=(10**1)/(2**4) */ |
michael@0 | 162 | ULL(0xc800000000000000), /* _Stl_tenpow[1]=(10**2)/(2**7) */ |
michael@0 | 163 | ULL(0xfa00000000000000), /* _Stl_tenpow[2]=(10**3)/(2**10) */ |
michael@0 | 164 | ULL(0x9c40000000000000), /* _Stl_tenpow[3]=(10**4)/(2**14) */ |
michael@0 | 165 | ULL(0xc350000000000000), /* _Stl_tenpow[4]=(10**5)/(2**17) */ |
michael@0 | 166 | ULL(0xf424000000000000), /* _Stl_tenpow[5]=(10**6)/(2**20) */ |
michael@0 | 167 | ULL(0x9896800000000000), /* _Stl_tenpow[6]=(10**7)/(2**24) */ |
michael@0 | 168 | ULL(0xbebc200000000000), /* _Stl_tenpow[7]=(10**8)/(2**27) */ |
michael@0 | 169 | ULL(0xee6b280000000000), /* _Stl_tenpow[8]=(10**9)/(2**30) */ |
michael@0 | 170 | ULL(0x9502f90000000000), /* _Stl_tenpow[9]=(10**10)/(2**34) */ |
michael@0 | 171 | ULL(0xba43b74000000000), /* _Stl_tenpow[10]=(10**11)/(2**37) */ |
michael@0 | 172 | ULL(0xe8d4a51000000000), /* _Stl_tenpow[11]=(10**12)/(2**40) */ |
michael@0 | 173 | ULL(0x9184e72a00000000), /* _Stl_tenpow[12]=(10**13)/(2**44) */ |
michael@0 | 174 | ULL(0xb5e620f480000000), /* _Stl_tenpow[13]=(10**14)/(2**47) */ |
michael@0 | 175 | ULL(0xe35fa931a0000000), /* _Stl_tenpow[14]=(10**15)/(2**50) */ |
michael@0 | 176 | ULL(0x8e1bc9bf04000000), /* _Stl_tenpow[15]=(10**16)/(2**54) */ |
michael@0 | 177 | ULL(0xb1a2bc2ec5000000), /* _Stl_tenpow[16]=(10**17)/(2**57) */ |
michael@0 | 178 | ULL(0xde0b6b3a76400000), /* _Stl_tenpow[17]=(10**18)/(2**60) */ |
michael@0 | 179 | ULL(0x8ac7230489e80000), /* _Stl_tenpow[18]=(10**19)/(2**64) */ |
michael@0 | 180 | ULL(0xad78ebc5ac620000), /* _Stl_tenpow[19]=(10**20)/(2**67) */ |
michael@0 | 181 | ULL(0xd8d726b7177a8000), /* _Stl_tenpow[20]=(10**21)/(2**70) */ |
michael@0 | 182 | ULL(0x878678326eac9000), /* _Stl_tenpow[21]=(10**22)/(2**74) */ |
michael@0 | 183 | ULL(0xa968163f0a57b400), /* _Stl_tenpow[22]=(10**23)/(2**77) */ |
michael@0 | 184 | ULL(0xd3c21bcecceda100), /* _Stl_tenpow[23]=(10**24)/(2**80) */ |
michael@0 | 185 | ULL(0x84595161401484a0), /* _Stl_tenpow[24]=(10**25)/(2**84) */ |
michael@0 | 186 | ULL(0xa56fa5b99019a5c8), /* _Stl_tenpow[25]=(10**26)/(2**87) */ |
michael@0 | 187 | ULL(0xcecb8f27f4200f3a), /* _Stl_tenpow[26]=(10**27)/(2**90) */ |
michael@0 | 188 | |
michael@0 | 189 | ULL(0xd0cf4b50cfe20766), /* _Stl_tenpow[27]=(10**55)/(2**183) */ |
michael@0 | 190 | ULL(0xd2d80db02aabd62c), /* _Stl_tenpow[28]=(10**83)/(2**276) */ |
michael@0 | 191 | ULL(0xd4e5e2cdc1d1ea96), /* _Stl_tenpow[29]=(10**111)/(2**369) */ |
michael@0 | 192 | ULL(0xd6f8d7509292d603), /* _Stl_tenpow[30]=(10**139)/(2**462) */ |
michael@0 | 193 | ULL(0xd910f7ff28069da4), /* _Stl_tenpow[31]=(10**167)/(2**555) */ |
michael@0 | 194 | ULL(0xdb2e51bfe9d0696a), /* _Stl_tenpow[32]=(10**195)/(2**648) */ |
michael@0 | 195 | ULL(0xdd50f1996b947519), /* _Stl_tenpow[33]=(10**223)/(2**741) */ |
michael@0 | 196 | ULL(0xdf78e4b2bd342cf7), /* _Stl_tenpow[34]=(10**251)/(2**834) */ |
michael@0 | 197 | ULL(0xe1a63853bbd26451), /* _Stl_tenpow[35]=(10**279)/(2**927) */ |
michael@0 | 198 | ULL(0xe3d8f9e563a198e5), /* _Stl_tenpow[36]=(10**307)/(2**1020) */ |
michael@0 | 199 | |
michael@0 | 200 | // /* _Stl_tenpow[36]=(10**335)/(2**) */ |
michael@0 | 201 | // /* _Stl_tenpow[36]=(10**335)/(2**) */ |
michael@0 | 202 | |
michael@0 | 203 | ULL(0xfd87b5f28300ca0e), /* _Stl_tenpow[37]=(10**-28)/(2**-93) */ |
michael@0 | 204 | ULL(0xfb158592be068d2f), /* _Stl_tenpow[38]=(10**-56)/(2**-186) */ |
michael@0 | 205 | ULL(0xf8a95fcf88747d94), /* _Stl_tenpow[39]=(10**-84)/(2**-279) */ |
michael@0 | 206 | ULL(0xf64335bcf065d37d), /* _Stl_tenpow[40]=(10**-112)/(2**-372) */ |
michael@0 | 207 | ULL(0xf3e2f893dec3f126), /* _Stl_tenpow[41]=(10**-140)/(2**-465) */ |
michael@0 | 208 | ULL(0xf18899b1bc3f8ca2), /* _Stl_tenpow[42]=(10**-168)/(2**-558) */ |
michael@0 | 209 | ULL(0xef340a98172aace5), /* _Stl_tenpow[43]=(10**-196)/(2**-651) */ |
michael@0 | 210 | ULL(0xece53cec4a314ebe), /* _Stl_tenpow[44]=(10**-224)/(2**-744) */ |
michael@0 | 211 | ULL(0xea9c227723ee8bcb), /* _Stl_tenpow[45]=(10**-252)/(2**-837) */ |
michael@0 | 212 | ULL(0xe858ad248f5c22ca), /* _Stl_tenpow[46]=(10**-280)/(2**-930) */ |
michael@0 | 213 | ULL(0xe61acf033d1a45df), /* _Stl_tenpow[47]=(10**-308)/(2**-1023) */ |
michael@0 | 214 | ULL(0xe3e27a444d8d98b8), /* _Stl_tenpow[48]=(10**-336)/(2**-1116) */ |
michael@0 | 215 | ULL(0xe1afa13afbd14d6e) /* _Stl_tenpow[49]=(10**-364)/(2**-1209) */ |
michael@0 | 216 | }; |
michael@0 | 217 | |
michael@0 | 218 | static const short _Stl_twoexp[80] = { |
michael@0 | 219 | 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, |
michael@0 | 220 | 183,276,369,462,555,648,741,834,927,1020, |
michael@0 | 221 | -93,-186,-279,-372,-465,-558,-651,-744,-837,-930,-1023,-1116,-1209 |
michael@0 | 222 | }; |
michael@0 | 223 | |
michael@0 | 224 | #define TEN_1 0 /* offset to 10 ** 1 */ |
michael@0 | 225 | #define TEN_27 26 /* offset to 10 ** 27 */ |
michael@0 | 226 | #define TEN_M28 37 /* offset to 10 ** -28 */ |
michael@0 | 227 | #define NUM_HI_P 11 |
michael@0 | 228 | #define NUM_HI_N 13 |
michael@0 | 229 | |
michael@0 | 230 | #define _Stl_HIBITULL (ULL(1) << 63) |
michael@0 | 231 | |
michael@0 | 232 | static void _Stl_norm_and_round(uint64& p, int& norm, uint64 prodhi, uint64 prodlo) { |
michael@0 | 233 | norm = 0; |
michael@0 | 234 | if ((prodhi & _Stl_HIBITULL) == 0) { |
michael@0 | 235 | /* leading bit is a zero |
michael@0 | 236 | * may have to normalize |
michael@0 | 237 | */ |
michael@0 | 238 | if ((prodhi == ~_Stl_HIBITULL) && |
michael@0 | 239 | ((prodlo >> 62) == 0x3)) { /* normalization followed by round |
michael@0 | 240 | * would cause carry to create |
michael@0 | 241 | * extra bit, so don't normalize |
michael@0 | 242 | */ |
michael@0 | 243 | p = _Stl_HIBITULL; |
michael@0 | 244 | return; |
michael@0 | 245 | } |
michael@0 | 246 | p = (prodhi << 1) | (prodlo >> 63); /* normalize */ |
michael@0 | 247 | norm = 1; |
michael@0 | 248 | prodlo <<= 1; |
michael@0 | 249 | } |
michael@0 | 250 | else { |
michael@0 | 251 | p = prodhi; |
michael@0 | 252 | } |
michael@0 | 253 | |
michael@0 | 254 | if ((prodlo & _Stl_HIBITULL) != 0) { /* first guard bit a one */ |
michael@0 | 255 | if (((p & 0x1) != 0) || |
michael@0 | 256 | prodlo != _Stl_HIBITULL ) { /* not borderline for round to even */ |
michael@0 | 257 | /* round */ |
michael@0 | 258 | ++p; |
michael@0 | 259 | if (p == 0) |
michael@0 | 260 | ++p; |
michael@0 | 261 | } |
michael@0 | 262 | } |
michael@0 | 263 | } |
michael@0 | 264 | |
michael@0 | 265 | // Convert a 64-bitb fraction * 10^exp to a 64-bit fraction * 2^bexp. |
michael@0 | 266 | // p: 64-bit fraction |
michael@0 | 267 | // exp: base-10 exponent |
michael@0 | 268 | // bexp: base-2 exponent (output parameter) |
michael@0 | 269 | static void _Stl_tenscale(uint64& p, int exp, int& bexp) { |
michael@0 | 270 | bexp = 0; |
michael@0 | 271 | |
michael@0 | 272 | if ( exp == 0 ) { /* no scaling needed */ |
michael@0 | 273 | return; |
michael@0 | 274 | } |
michael@0 | 275 | |
michael@0 | 276 | int exp_hi = 0, exp_lo = exp; /* exp = exp_hi*32 + exp_lo */ |
michael@0 | 277 | int tlo = TEN_1, thi; /* offsets in power of ten table */ |
michael@0 | 278 | int num_hi; /* number of high exponent powers */ |
michael@0 | 279 | |
michael@0 | 280 | if (exp > 0) { /* split exponent */ |
michael@0 | 281 | if (exp_lo > 27) { |
michael@0 | 282 | exp_lo++; |
michael@0 | 283 | while (exp_lo > 27) { |
michael@0 | 284 | exp_hi++; |
michael@0 | 285 | exp_lo -= 28; |
michael@0 | 286 | } |
michael@0 | 287 | } |
michael@0 | 288 | thi = TEN_27; |
michael@0 | 289 | num_hi = NUM_HI_P; |
michael@0 | 290 | } else { // exp < 0 |
michael@0 | 291 | while (exp_lo < 0) { |
michael@0 | 292 | exp_hi++; |
michael@0 | 293 | exp_lo += 28; |
michael@0 | 294 | } |
michael@0 | 295 | thi = TEN_M28; |
michael@0 | 296 | num_hi = NUM_HI_N; |
michael@0 | 297 | } |
michael@0 | 298 | |
michael@0 | 299 | uint64 prodhi, prodlo; /* 128b product */ |
michael@0 | 300 | int norm; /* number of bits of normalization */ |
michael@0 | 301 | |
michael@0 | 302 | int hi, lo; /* offsets in power of ten table */ |
michael@0 | 303 | while (exp_hi) { /* scale */ |
michael@0 | 304 | hi = (min) (exp_hi, num_hi); /* only a few large powers of 10 */ |
michael@0 | 305 | exp_hi -= hi; /* could iterate in extreme case */ |
michael@0 | 306 | hi += thi-1; |
michael@0 | 307 | _Stl_mult64(p, _Stl_tenpow[hi], prodhi, prodlo); |
michael@0 | 308 | _Stl_norm_and_round(p, norm, prodhi, prodlo); |
michael@0 | 309 | bexp += _Stl_twoexp[hi] - norm; |
michael@0 | 310 | } |
michael@0 | 311 | |
michael@0 | 312 | if (exp_lo) { |
michael@0 | 313 | lo = tlo + exp_lo -1; |
michael@0 | 314 | _Stl_mult64(p, _Stl_tenpow[lo], prodhi, prodlo); |
michael@0 | 315 | _Stl_norm_and_round(p, norm, prodhi, prodlo); |
michael@0 | 316 | bexp += _Stl_twoexp[lo] - norm; |
michael@0 | 317 | } |
michael@0 | 318 | |
michael@0 | 319 | return; |
michael@0 | 320 | } |
michael@0 | 321 | |
michael@0 | 322 | // First argument is a buffer of values from 0 to 9, NOT ascii. |
michael@0 | 323 | // Second argument is number of digits in buffer, 1 <= digits <= 17. |
michael@0 | 324 | // Third argument is base-10 exponent. |
michael@0 | 325 | |
michael@0 | 326 | /* IEEE representation */ |
michael@0 | 327 | #if !defined (__linux__) || defined (__ANDROID__) |
michael@0 | 328 | |
michael@0 | 329 | union _Double_rep { |
michael@0 | 330 | uint64 ival; |
michael@0 | 331 | double val; |
michael@0 | 332 | }; |
michael@0 | 333 | |
michael@0 | 334 | static double _Stl_atod(char *buffer, ptrdiff_t ndigit, int dexp) { |
michael@0 | 335 | typedef numeric_limits<double> limits; |
michael@0 | 336 | _Double_rep drep; |
michael@0 | 337 | uint64 &value = drep.ival; /* Value develops as follows: |
michael@0 | 338 | * 1) decimal digits as an integer |
michael@0 | 339 | * 2) left adjusted fraction |
michael@0 | 340 | * 3) right adjusted fraction |
michael@0 | 341 | * 4) exponent and fraction |
michael@0 | 342 | */ |
michael@0 | 343 | |
michael@0 | 344 | uint32 guard; /* First guard bit */ |
michael@0 | 345 | uint64 rest; /* Remaining guard bits */ |
michael@0 | 346 | |
michael@0 | 347 | int bexp; /* binary exponent */ |
michael@0 | 348 | int nzero; /* number of non-zero bits */ |
michael@0 | 349 | int sexp; /* scaling exponent */ |
michael@0 | 350 | |
michael@0 | 351 | char *bufferend; /* pointer to char after last digit */ |
michael@0 | 352 | |
michael@0 | 353 | /* Convert the decimal digits to a binary integer. */ |
michael@0 | 354 | bufferend = buffer + ndigit; |
michael@0 | 355 | value = 0; |
michael@0 | 356 | |
michael@0 | 357 | while (buffer < bufferend) { |
michael@0 | 358 | value *= 10; |
michael@0 | 359 | value += *buffer++; |
michael@0 | 360 | } |
michael@0 | 361 | |
michael@0 | 362 | /* Check for zero and treat it as a special case */ |
michael@0 | 363 | if (value == 0) { |
michael@0 | 364 | return 0.0; |
michael@0 | 365 | } |
michael@0 | 366 | |
michael@0 | 367 | /* Normalize value */ |
michael@0 | 368 | bexp = 64; /* convert from 64b int to fraction */ |
michael@0 | 369 | |
michael@0 | 370 | /* Count number of non-zeroes in value */ |
michael@0 | 371 | nzero = 0; |
michael@0 | 372 | if ((value >> 32) != 0) { nzero = 32; } //*TY 03/25/2000 - added explicit comparison to zero to avoid uint64 to bool conversion operator |
michael@0 | 373 | if ((value >> (16 + nzero)) != 0) { nzero += 16; } |
michael@0 | 374 | if ((value >> ( 8 + nzero)) != 0) { nzero += 8; } |
michael@0 | 375 | if ((value >> ( 4 + nzero)) != 0) { nzero += 4; } |
michael@0 | 376 | if ((value >> ( 2 + nzero)) != 0) { nzero += 2; } |
michael@0 | 377 | if ((value >> ( 1 + nzero)) != 0) { nzero += 1; } |
michael@0 | 378 | if ((value >> ( nzero)) != 0) { nzero += 1; } |
michael@0 | 379 | |
michael@0 | 380 | /* Normalize */ |
michael@0 | 381 | value <<= /*(uint64)*/ (64 - nzero); //*TY 03/25/2000 - removed extraneous cast to uint64 |
michael@0 | 382 | bexp -= 64 - nzero; |
michael@0 | 383 | |
michael@0 | 384 | /* At this point we have a 64b fraction and a binary exponent |
michael@0 | 385 | * but have yet to incorporate the decimal exponent. |
michael@0 | 386 | */ |
michael@0 | 387 | |
michael@0 | 388 | /* multiply by 10^dexp */ |
michael@0 | 389 | _Stl_tenscale(value, dexp, sexp); |
michael@0 | 390 | bexp += sexp; |
michael@0 | 391 | |
michael@0 | 392 | if (bexp <= -1022) { /* HI denorm or underflow */ |
michael@0 | 393 | bexp += 1022; |
michael@0 | 394 | if (bexp < -53) { /* guaranteed underflow */ |
michael@0 | 395 | value = 0; |
michael@0 | 396 | } |
michael@0 | 397 | else { /* denorm or possible underflow */ |
michael@0 | 398 | int lead0 = 12 - bexp; /* 12 sign and exponent bits */ |
michael@0 | 399 | |
michael@0 | 400 | /* we must special case right shifts of more than 63 */ |
michael@0 | 401 | if (lead0 > 64) { |
michael@0 | 402 | rest = value; |
michael@0 | 403 | guard = 0; |
michael@0 | 404 | value = 0; |
michael@0 | 405 | } |
michael@0 | 406 | else if (lead0 == 64) { |
michael@0 | 407 | rest = value & ((ULL(1)<< 63)-1); |
michael@0 | 408 | guard = (uint32) ((value>> 63) & 1 ); |
michael@0 | 409 | value = 0; |
michael@0 | 410 | } |
michael@0 | 411 | else { |
michael@0 | 412 | rest = value & (((ULL(1) << lead0)-1)-1); |
michael@0 | 413 | guard = (uint32) (((value>> lead0)-1) & 1); |
michael@0 | 414 | value >>= /*(uint64)*/ lead0; /* exponent is zero */ |
michael@0 | 415 | } |
michael@0 | 416 | |
michael@0 | 417 | /* Round */ |
michael@0 | 418 | if (guard && ((value & 1) || rest) ) { |
michael@0 | 419 | ++value; |
michael@0 | 420 | if (value == (ULL(1) << (limits::digits - 1))) { /* carry created normal number */ |
michael@0 | 421 | value = 0; |
michael@0 | 422 | _Stl_set_exponent(value, 1); |
michael@0 | 423 | } |
michael@0 | 424 | } |
michael@0 | 425 | } |
michael@0 | 426 | } |
michael@0 | 427 | else { /* not zero or denorm */ |
michael@0 | 428 | /* Round to 53 bits */ |
michael@0 | 429 | rest = value & ((1 << 10) - 1); |
michael@0 | 430 | value >>= 10; |
michael@0 | 431 | guard = (uint32) value & 1; |
michael@0 | 432 | value >>= 1; |
michael@0 | 433 | |
michael@0 | 434 | /* value&1 guard rest Action |
michael@0 | 435 | * |
michael@0 | 436 | * dc 0 dc none |
michael@0 | 437 | * 1 1 dc round |
michael@0 | 438 | * 0 1 0 none |
michael@0 | 439 | * 0 1 !=0 round |
michael@0 | 440 | */ |
michael@0 | 441 | if (guard) { |
michael@0 | 442 | if (((value&1)!=0) || (rest!=0)) { |
michael@0 | 443 | ++value; /* round */ |
michael@0 | 444 | if ((value >> 53) != 0) { /* carry all the way across */ |
michael@0 | 445 | value >>= 1; /* renormalize */ |
michael@0 | 446 | ++bexp; |
michael@0 | 447 | } |
michael@0 | 448 | } |
michael@0 | 449 | } |
michael@0 | 450 | /* |
michael@0 | 451 | * Check for overflow |
michael@0 | 452 | * IEEE Double Precision Format |
michael@0 | 453 | * (From Table 7-8 of Kane and Heinrich) |
michael@0 | 454 | * |
michael@0 | 455 | * Fraction bits 52 |
michael@0 | 456 | * Emax +1023 |
michael@0 | 457 | * Emin -1022 |
michael@0 | 458 | * Exponent bias +1023 |
michael@0 | 459 | * Exponent bits 11 |
michael@0 | 460 | * Integer bit hidden |
michael@0 | 461 | * Total width in bits 64 |
michael@0 | 462 | */ |
michael@0 | 463 | |
michael@0 | 464 | if (bexp > limits::max_exponent) { /* overflow */ |
michael@0 | 465 | return limits::infinity(); |
michael@0 | 466 | } |
michael@0 | 467 | else { /* value is normal */ |
michael@0 | 468 | value &= ~(ULL(1) << (limits::digits - 1)); /* hide hidden bit */ |
michael@0 | 469 | _Stl_set_exponent(value, bexp + 1022); /* add bias */ |
michael@0 | 470 | } |
michael@0 | 471 | } |
michael@0 | 472 | |
michael@0 | 473 | _STLP_STATIC_ASSERT(sizeof(uint64) >= sizeof(double)) |
michael@0 | 474 | return drep.val; |
michael@0 | 475 | } |
michael@0 | 476 | |
michael@0 | 477 | #endif |
michael@0 | 478 | |
michael@0 | 479 | #if defined (__linux__) || defined (__MINGW32__) || defined (__CYGWIN__) || \ |
michael@0 | 480 | defined (__BORLANDC__) || defined (__DMC__) || defined (__HP_aCC) |
michael@0 | 481 | |
michael@0 | 482 | template <class D, class IEEE, int M, int BIAS> |
michael@0 | 483 | D _Stl_atodT(char *buffer, ptrdiff_t ndigit, int dexp) |
michael@0 | 484 | { |
michael@0 | 485 | typedef numeric_limits<D> limits; |
michael@0 | 486 | |
michael@0 | 487 | /* Convert the decimal digits to a binary integer. */ |
michael@0 | 488 | char *bufferend = buffer + ndigit; /* pointer to char after last digit */ |
michael@0 | 489 | _ll vv; |
michael@0 | 490 | vv.i64 = 0L; |
michael@0 | 491 | |
michael@0 | 492 | while ( buffer < bufferend ) { |
michael@0 | 493 | vv.i64 *= 10; |
michael@0 | 494 | vv.i64 += *buffer++; |
michael@0 | 495 | } |
michael@0 | 496 | |
michael@0 | 497 | if ( vv.i64 == ULL(0) ) { /* Check for zero and treat it as a special case */ |
michael@0 | 498 | return D(0.0); |
michael@0 | 499 | } |
michael@0 | 500 | |
michael@0 | 501 | /* Normalize value */ |
michael@0 | 502 | |
michael@0 | 503 | int bexp = 64; /* convert from 64b int to fraction */ |
michael@0 | 504 | |
michael@0 | 505 | /* Count number of non-zeroes in value */ |
michael@0 | 506 | int nzero = 0; |
michael@0 | 507 | if ((vv.i64 >> 32) != 0) { nzero = 32; } |
michael@0 | 508 | if ((vv.i64 >> (16 + nzero)) != 0) { nzero += 16; } |
michael@0 | 509 | if ((vv.i64 >> ( 8 + nzero)) != 0) { nzero += 8; } |
michael@0 | 510 | if ((vv.i64 >> ( 4 + nzero)) != 0) { nzero += 4; } |
michael@0 | 511 | if ((vv.i64 >> ( 2 + nzero)) != 0) { nzero += 2; } |
michael@0 | 512 | if ((vv.i64 >> ( 1 + nzero)) != 0) { nzero += 1; } |
michael@0 | 513 | if ((vv.i64 >> ( nzero)) != 0) { nzero += 1; } |
michael@0 | 514 | |
michael@0 | 515 | /* Normalize */ |
michael@0 | 516 | nzero = 64 - nzero; |
michael@0 | 517 | vv.i64 <<= nzero; // * TY 03/25/2000 - removed extraneous cast to uint64 |
michael@0 | 518 | bexp -= nzero; |
michael@0 | 519 | |
michael@0 | 520 | /* At this point we have a 64b fraction and a binary exponent |
michael@0 | 521 | * but have yet to incorporate the decimal exponent. |
michael@0 | 522 | */ |
michael@0 | 523 | |
michael@0 | 524 | /* multiply by 10^dexp */ |
michael@0 | 525 | int sexp; |
michael@0 | 526 | _Stl_tenscale(vv.i64, dexp, sexp); |
michael@0 | 527 | bexp += sexp; |
michael@0 | 528 | |
michael@0 | 529 | if ( bexp >= limits::min_exponent ) { /* not zero or denorm */ |
michael@0 | 530 | if ( limits::digits < 64 ) { |
michael@0 | 531 | /* Round to (64 - M + 1) bits */ |
michael@0 | 532 | uint64_t rest = vv.i64 & ((~ULL(0) / ULL(2)) >> (limits::digits - 1)); |
michael@0 | 533 | vv.i64 >>= M - 2; |
michael@0 | 534 | uint32_t guard = (uint32) vv.i64 & 1; |
michael@0 | 535 | vv.i64 >>= 1; |
michael@0 | 536 | |
michael@0 | 537 | /* value&1 guard rest Action |
michael@0 | 538 | * |
michael@0 | 539 | * dc 0 dc none |
michael@0 | 540 | * 1 1 dc round |
michael@0 | 541 | * 0 1 0 none |
michael@0 | 542 | * 0 1 !=0 round |
michael@0 | 543 | */ |
michael@0 | 544 | |
michael@0 | 545 | if (guard) { |
michael@0 | 546 | if ( ((vv.i64 & 1) != 0) || (rest != 0) ) { |
michael@0 | 547 | vv.i64++; /* round */ |
michael@0 | 548 | if ( (vv.i64 >> (limits::digits < 64 ? limits::digits : 0)) != 0 ) { /* carry all the way across */ |
michael@0 | 549 | vv.i64 >>= 1; /* renormalize */ |
michael@0 | 550 | ++bexp; |
michael@0 | 551 | } |
michael@0 | 552 | } |
michael@0 | 553 | } |
michael@0 | 554 | |
michael@0 | 555 | vv.i64 &= ~(ULL(1) << (limits::digits - 1)); /* hide hidden bit */ |
michael@0 | 556 | } |
michael@0 | 557 | /* |
michael@0 | 558 | * Check for overflow |
michael@0 | 559 | * IEEE Double Precision Format |
michael@0 | 560 | * (From Table 7-8 of Kane and Heinrich) |
michael@0 | 561 | * |
michael@0 | 562 | * Fraction bits 52 |
michael@0 | 563 | * Emax +1023 |
michael@0 | 564 | * Emin -1022 |
michael@0 | 565 | * Exponent bias +1023 |
michael@0 | 566 | * Exponent bits 11 |
michael@0 | 567 | * Integer bit hidden |
michael@0 | 568 | * Total width in bits 64 |
michael@0 | 569 | */ |
michael@0 | 570 | |
michael@0 | 571 | if (bexp > limits::max_exponent) { /* overflow */ |
michael@0 | 572 | return limits::infinity(); |
michael@0 | 573 | } |
michael@0 | 574 | |
michael@0 | 575 | /* value is normal */ |
michael@0 | 576 | |
michael@0 | 577 | IEEE v; |
michael@0 | 578 | |
michael@0 | 579 | v.ieee.mantissa0 = vv.i32.hi; |
michael@0 | 580 | v.ieee.mantissa1 = vv.i32.lo; |
michael@0 | 581 | v.ieee.negative = 0; |
michael@0 | 582 | v.ieee.exponent = bexp + BIAS - 1; |
michael@0 | 583 | |
michael@0 | 584 | return v.d; |
michael@0 | 585 | } |
michael@0 | 586 | |
michael@0 | 587 | /* HI denorm or underflow */ |
michael@0 | 588 | bexp += BIAS - 1; |
michael@0 | 589 | if (bexp < -limits::digits) { /* guaranteed underflow */ |
michael@0 | 590 | vv.i64 = 0; |
michael@0 | 591 | } else { /* denorm or possible underflow */ |
michael@0 | 592 | |
michael@0 | 593 | /* |
michael@0 | 594 | * Problem point for long double: looks like this code reflect shareing of mantissa |
michael@0 | 595 | * and exponent in 64b int; not so for long double |
michael@0 | 596 | */ |
michael@0 | 597 | |
michael@0 | 598 | int lead0 = M - bexp; /* M = 12 sign and exponent bits */ |
michael@0 | 599 | uint64_t rest; |
michael@0 | 600 | uint32_t guard; |
michael@0 | 601 | |
michael@0 | 602 | /* we must special case right shifts of more than 63 */ |
michael@0 | 603 | |
michael@0 | 604 | if (lead0 > 64) { |
michael@0 | 605 | rest = vv.i64; |
michael@0 | 606 | guard = 0; |
michael@0 | 607 | vv.i64 = 0; |
michael@0 | 608 | } else if (lead0 == 64) { |
michael@0 | 609 | rest = vv.i64 & ((ULL(1) << 63)-1); |
michael@0 | 610 | guard = (uint32) ((vv.i64 >> 63) & 1 ); |
michael@0 | 611 | vv.i64 = 0; |
michael@0 | 612 | } else { |
michael@0 | 613 | rest = vv.i64 & (((ULL(1) << lead0)-1)-1); |
michael@0 | 614 | guard = (uint32) (((vv.i64 >> lead0)-1) & 1); |
michael@0 | 615 | vv.i64 >>= /*(uint64)*/ lead0; /* exponent is zero */ |
michael@0 | 616 | } |
michael@0 | 617 | |
michael@0 | 618 | /* Round */ |
michael@0 | 619 | if (guard && ( (vv.i64 & 1) || rest)) { |
michael@0 | 620 | vv.i64++; |
michael@0 | 621 | if (vv.i64 == (ULL(1) << (limits::digits - 1))) { /* carry created normal number */ |
michael@0 | 622 | IEEE v; |
michael@0 | 623 | |
michael@0 | 624 | v.ieee.mantissa0 = 0; |
michael@0 | 625 | v.ieee.mantissa1 = 0; |
michael@0 | 626 | v.ieee.negative = 0; |
michael@0 | 627 | v.ieee.exponent = 1; |
michael@0 | 628 | return v.d; |
michael@0 | 629 | } |
michael@0 | 630 | } |
michael@0 | 631 | } |
michael@0 | 632 | |
michael@0 | 633 | IEEE v; |
michael@0 | 634 | |
michael@0 | 635 | v.ieee.mantissa0 = vv.i32.hi; |
michael@0 | 636 | v.ieee.mantissa1 = vv.i32.lo; |
michael@0 | 637 | v.ieee.negative = 0; |
michael@0 | 638 | v.ieee.exponent = 0; |
michael@0 | 639 | |
michael@0 | 640 | return v.d; |
michael@0 | 641 | } |
michael@0 | 642 | #endif // __linux__ |
michael@0 | 643 | |
michael@0 | 644 | #if !defined (__linux__) || defined (__ANDROID__) |
michael@0 | 645 | static double _Stl_string_to_double(const char *s) { |
michael@0 | 646 | typedef numeric_limits<double> limits; |
michael@0 | 647 | const int max_digits = limits::digits10 + 2; |
michael@0 | 648 | unsigned c; |
michael@0 | 649 | unsigned Negate, decimal_point; |
michael@0 | 650 | char *d; |
michael@0 | 651 | int exp; |
michael@0 | 652 | int dpchar; |
michael@0 | 653 | char digits[max_digits]; |
michael@0 | 654 | |
michael@0 | 655 | c = *s++; |
michael@0 | 656 | |
michael@0 | 657 | /* process sign */ |
michael@0 | 658 | Negate = 0; |
michael@0 | 659 | if (c == '+') { |
michael@0 | 660 | c = *s++; |
michael@0 | 661 | } else if (c == '-') { |
michael@0 | 662 | Negate = 1; |
michael@0 | 663 | c = *s++; |
michael@0 | 664 | } |
michael@0 | 665 | |
michael@0 | 666 | d = digits; |
michael@0 | 667 | dpchar = '.' - '0'; |
michael@0 | 668 | decimal_point = 0; |
michael@0 | 669 | exp = 0; |
michael@0 | 670 | |
michael@0 | 671 | for (;;) { |
michael@0 | 672 | c -= '0'; |
michael@0 | 673 | if (c < 10) { |
michael@0 | 674 | if (d == digits + max_digits) { |
michael@0 | 675 | /* ignore more than max_digits digits, but adjust exponent */ |
michael@0 | 676 | exp += (decimal_point ^ 1); |
michael@0 | 677 | } else { |
michael@0 | 678 | if (c == 0 && d == digits) { |
michael@0 | 679 | /* ignore leading zeros */ |
michael@0 | 680 | } else { |
michael@0 | 681 | *d++ = (char) c; |
michael@0 | 682 | } |
michael@0 | 683 | exp -= decimal_point; |
michael@0 | 684 | } |
michael@0 | 685 | } else if (c == (unsigned int) dpchar && !decimal_point) { /* INTERNATIONAL */ |
michael@0 | 686 | decimal_point = 1; |
michael@0 | 687 | } else { |
michael@0 | 688 | break; |
michael@0 | 689 | } |
michael@0 | 690 | c = *s++; |
michael@0 | 691 | } |
michael@0 | 692 | |
michael@0 | 693 | /* strtod cant return until it finds the end of the exponent */ |
michael@0 | 694 | if (d == digits) { |
michael@0 | 695 | return 0.0; |
michael@0 | 696 | } |
michael@0 | 697 | |
michael@0 | 698 | if (c == 'e' - '0' || c == 'E' - '0') { |
michael@0 | 699 | register unsigned negate_exp = 0; |
michael@0 | 700 | register int e = 0; |
michael@0 | 701 | c = *s++; |
michael@0 | 702 | if (c == '+' || c == ' ') { |
michael@0 | 703 | c = *s++; |
michael@0 | 704 | } else if (c == '-') { |
michael@0 | 705 | negate_exp = 1; |
michael@0 | 706 | c = *s++; |
michael@0 | 707 | } |
michael@0 | 708 | if (c -= '0', c < 10) { |
michael@0 | 709 | do { |
michael@0 | 710 | e = e * 10 + (int)c; |
michael@0 | 711 | c = *s++; |
michael@0 | 712 | } while (c -= '0', c < 10); |
michael@0 | 713 | |
michael@0 | 714 | if (negate_exp) { |
michael@0 | 715 | e = -e; |
michael@0 | 716 | } |
michael@0 | 717 | exp += e; |
michael@0 | 718 | } |
michael@0 | 719 | } |
michael@0 | 720 | |
michael@0 | 721 | double x; |
michael@0 | 722 | ptrdiff_t n = d - digits; |
michael@0 | 723 | if ((exp + n - 1) < limits::min_exponent10) { |
michael@0 | 724 | x = 0; |
michael@0 | 725 | } |
michael@0 | 726 | else if ((exp + n - 1) > limits::max_exponent10) { |
michael@0 | 727 | x = limits::infinity(); |
michael@0 | 728 | } |
michael@0 | 729 | else { |
michael@0 | 730 | /* Let _Stl_atod diagnose under- and over-flows. |
michael@0 | 731 | * If the input was == 0.0, we have already returned, |
michael@0 | 732 | * so retval of +-Inf signals OVERFLOW, 0.0 UNDERFLOW */ |
michael@0 | 733 | x = _Stl_atod(digits, n, exp); |
michael@0 | 734 | } |
michael@0 | 735 | |
michael@0 | 736 | if (Negate) { |
michael@0 | 737 | x = -x; |
michael@0 | 738 | } |
michael@0 | 739 | |
michael@0 | 740 | return x; |
michael@0 | 741 | } |
michael@0 | 742 | |
michael@0 | 743 | #endif |
michael@0 | 744 | |
michael@0 | 745 | #if defined (__linux__) || defined (__MINGW32__) || defined (__CYGWIN__) || \ |
michael@0 | 746 | defined (__BORLANDC__) || defined (__DMC__) || defined (__HP_aCC) |
michael@0 | 747 | |
michael@0 | 748 | template <class D, class IEEE, int M, int BIAS> |
michael@0 | 749 | D _Stl_string_to_doubleT(const char *s) |
michael@0 | 750 | { |
michael@0 | 751 | typedef numeric_limits<D> limits; |
michael@0 | 752 | const int max_digits = limits::digits10; /* + 2 17 */; |
michael@0 | 753 | unsigned c; |
michael@0 | 754 | unsigned decimal_point; |
michael@0 | 755 | char *d; |
michael@0 | 756 | int exp; |
michael@0 | 757 | D x; |
michael@0 | 758 | int dpchar; |
michael@0 | 759 | char digits[max_digits]; |
michael@0 | 760 | |
michael@0 | 761 | c = *s++; |
michael@0 | 762 | |
michael@0 | 763 | /* process sign */ |
michael@0 | 764 | bool Negate = false; |
michael@0 | 765 | if (c == '+') { |
michael@0 | 766 | c = *s++; |
michael@0 | 767 | } else if (c == '-') { |
michael@0 | 768 | Negate = true; |
michael@0 | 769 | c = *s++; |
michael@0 | 770 | } |
michael@0 | 771 | |
michael@0 | 772 | d = digits; |
michael@0 | 773 | dpchar = '.' - '0'; |
michael@0 | 774 | decimal_point = 0; |
michael@0 | 775 | exp = 0; |
michael@0 | 776 | |
michael@0 | 777 | for (;;) { |
michael@0 | 778 | c -= '0'; |
michael@0 | 779 | if (c < 10) { |
michael@0 | 780 | if (d == digits + max_digits) { |
michael@0 | 781 | /* ignore more than max_digits digits, but adjust exponent */ |
michael@0 | 782 | exp += (decimal_point ^ 1); |
michael@0 | 783 | } else { |
michael@0 | 784 | if (c == 0 && d == digits) { |
michael@0 | 785 | /* ignore leading zeros */ |
michael@0 | 786 | } else { |
michael@0 | 787 | *d++ = (char) c; |
michael@0 | 788 | } |
michael@0 | 789 | exp -= decimal_point; |
michael@0 | 790 | } |
michael@0 | 791 | } else if (c == (unsigned int) dpchar && !decimal_point) { /* INTERNATIONAL */ |
michael@0 | 792 | decimal_point = 1; |
michael@0 | 793 | } else { |
michael@0 | 794 | break; |
michael@0 | 795 | } |
michael@0 | 796 | c = *s++; |
michael@0 | 797 | } |
michael@0 | 798 | /* strtod cant return until it finds the end of the exponent */ |
michael@0 | 799 | if (d == digits) { |
michael@0 | 800 | return D(0.0); |
michael@0 | 801 | } |
michael@0 | 802 | |
michael@0 | 803 | if (c == 'e'-'0' || c == 'E'-'0') { |
michael@0 | 804 | bool negate_exp = false; |
michael@0 | 805 | register int e = 0; |
michael@0 | 806 | c = *s++; |
michael@0 | 807 | if (c == '+' || c == ' ') { |
michael@0 | 808 | c = *s++; |
michael@0 | 809 | } else if (c == '-') { |
michael@0 | 810 | negate_exp = true; |
michael@0 | 811 | c = *s++; |
michael@0 | 812 | } |
michael@0 | 813 | if (c -= '0', c < 10) { |
michael@0 | 814 | do { |
michael@0 | 815 | e = e * 10 + (int)c; |
michael@0 | 816 | c = *s++; |
michael@0 | 817 | } while (c -= '0', c < 10); |
michael@0 | 818 | |
michael@0 | 819 | if (negate_exp) { |
michael@0 | 820 | e = -e; |
michael@0 | 821 | } |
michael@0 | 822 | exp += e; |
michael@0 | 823 | } |
michael@0 | 824 | } |
michael@0 | 825 | |
michael@0 | 826 | ptrdiff_t n = d - digits; |
michael@0 | 827 | if ((exp + n - 1) < limits::min_exponent10) { |
michael@0 | 828 | return D(0.0); // +0.0 is the same as -0.0 |
michael@0 | 829 | } else if ((exp + n - 1) > limits::max_exponent10 ) { |
michael@0 | 830 | // not good, because of x = -x below; this may lead to portability problems |
michael@0 | 831 | x = limits::infinity(); |
michael@0 | 832 | } else { |
michael@0 | 833 | /* let _Stl_atod diagnose under- and over-flows */ |
michael@0 | 834 | /* if the input was == 0.0, we have already returned, |
michael@0 | 835 | so retval of +-Inf signals OVERFLOW, 0.0 UNDERFLOW |
michael@0 | 836 | */ |
michael@0 | 837 | x = _Stl_atodT<D,IEEE,M,BIAS>(digits, n, exp); |
michael@0 | 838 | } |
michael@0 | 839 | |
michael@0 | 840 | return Negate ? -x : x; |
michael@0 | 841 | } |
michael@0 | 842 | |
michael@0 | 843 | #endif // __linux__ |
michael@0 | 844 | |
michael@0 | 845 | void _STLP_CALL |
michael@0 | 846 | __string_to_float(const __iostring& v, float& val) |
michael@0 | 847 | { |
michael@0 | 848 | #if !defined (__linux__) || defined (__ANDROID__) |
michael@0 | 849 | val = (float)_Stl_string_to_double(v.c_str()); |
michael@0 | 850 | #else |
michael@0 | 851 | val = (float)_Stl_string_to_doubleT<double,ieee754_double,12,IEEE754_DOUBLE_BIAS>(v.c_str()); |
michael@0 | 852 | #endif |
michael@0 | 853 | } |
michael@0 | 854 | |
michael@0 | 855 | void _STLP_CALL |
michael@0 | 856 | __string_to_float(const __iostring& v, double& val) |
michael@0 | 857 | { |
michael@0 | 858 | #if !defined (__linux__) || defined (__ANDROID__) |
michael@0 | 859 | val = _Stl_string_to_double(v.c_str()); |
michael@0 | 860 | #else |
michael@0 | 861 | val = _Stl_string_to_doubleT<double,ieee754_double,12,IEEE754_DOUBLE_BIAS>(v.c_str()); |
michael@0 | 862 | #endif |
michael@0 | 863 | } |
michael@0 | 864 | |
michael@0 | 865 | #if !defined (_STLP_NO_LONG_DOUBLE) |
michael@0 | 866 | void _STLP_CALL |
michael@0 | 867 | __string_to_float(const __iostring& v, long double& val) { |
michael@0 | 868 | #if !defined (__linux__) && !defined (__MINGW32__) && !defined (__CYGWIN__) && \ |
michael@0 | 869 | !defined (__BORLANDC__) && !defined (__DMC__) && !defined (__HP_aCC) |
michael@0 | 870 | //The following function is valid only if long double is an alias for double. |
michael@0 | 871 | _STLP_STATIC_ASSERT( sizeof(long double) <= sizeof(double) ) |
michael@0 | 872 | val = _Stl_string_to_double(v.c_str()); |
michael@0 | 873 | #else |
michael@0 | 874 | val = _Stl_string_to_doubleT<long double,ieee854_long_double,16,IEEE854_LONG_DOUBLE_BIAS>(v.c_str()); |
michael@0 | 875 | #endif |
michael@0 | 876 | } |
michael@0 | 877 | #endif |
michael@0 | 878 | |
michael@0 | 879 | _STLP_MOVE_TO_STD_NAMESPACE |
michael@0 | 880 | _STLP_END_NAMESPACE |
michael@0 | 881 | |
michael@0 | 882 | // Local Variables: |
michael@0 | 883 | // mode:C++ |
michael@0 | 884 | // End: |