1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cppstdlib/stl/src/num_get_float.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1000 @@
1.4 +/*
1.5 + * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
1.6 + *
1.7 + * Copyright (c) 1999
1.8 + * Silicon Graphics Computer Systems, Inc.
1.9 + *
1.10 + * Copyright (c) 1999
1.11 + * Boris Fomitchev
1.12 + *
1.13 + * This material is provided "as is", with absolutely no warranty expressed
1.14 + * or implied. Any use is at your own risk.
1.15 + *
1.16 + * Permission to use or copy this software for any purpose is hereby granted
1.17 + * without fee, provided the above notices are retained on all copies.
1.18 + * Permission to modify the code and to distribute modified code is granted,
1.19 + * provided the above notices are retained, and a notice that the code was
1.20 + * modified is included with the above copyright notice.
1.21 + *
1.22 + */
1.23 +
1.24 +#include "stlport_prefix.h"
1.25 +
1.26 +#include <limits>
1.27 +#include <locale>
1.28 +#include <istream>
1.29 +
1.30 +#if defined (__GNUC__) && !defined (__sun) || \
1.31 + defined (__DMC__)
1.32 +# include <stdint.h>
1.33 +#endif
1.34 +
1.35 +#if defined (__linux__)
1.36 +# include <ieee754.h>
1.37 +
1.38 +union _ll {
1.39 + uint64_t i64;
1.40 + struct {
1.41 +# if defined (_STLP_BIG_ENDIAN)
1.42 + uint32_t hi;
1.43 + uint32_t lo;
1.44 +# elif defined (_STLP_LITTLE_ENDIAN)
1.45 + uint32_t lo;
1.46 + uint32_t hi;
1.47 +# else
1.48 +# error Unknown endianess
1.49 +# endif
1.50 + } i32;
1.51 +};
1.52 +#endif
1.53 +
1.54 +#if defined (N_PLAT_NLM)
1.55 +# include <nlm/nwintxx.h>
1.56 +
1.57 +# if defined (INT64)
1.58 +typedef unsigned INT64 uint64_t;
1.59 +# else
1.60 +// #error "Can't find INT64"
1.61 +// 64-bit int really not defined in headers
1.62 +// (_INTEGRAL_MAX_BITS < 64 in any case?), but compiler indeed know __int64
1.63 +// - ptr, 2005-05-06
1.64 +typedef unsigned __int64 uint64_t;
1.65 +# endif
1.66 +
1.67 +# if defined (INT32)
1.68 +typedef unsigned INT32 uint32_t;
1.69 +# else
1.70 +# error Can not find INT32
1.71 +# endif
1.72 +
1.73 +union _ll {
1.74 + uint64_t i64;
1.75 + struct {
1.76 + uint32_t lo;
1.77 + uint32_t hi;
1.78 + } i32;
1.79 +};
1.80 +#endif
1.81 +
1.82 +_STLP_BEGIN_NAMESPACE
1.83 +_STLP_MOVE_TO_PRIV_NAMESPACE
1.84 +
1.85 +//----------------------------------------------------------------------
1.86 +// num_get
1.87 +
1.88 +// Helper functions for _M_do_get_float.
1.89 +
1.90 +#if !defined (_STLP_NO_WCHAR_T)
1.91 +void _STLP_DECLSPEC _STLP_CALL
1.92 +_Initialize_get_float( const ctype<wchar_t>& ct,
1.93 + wchar_t& Plus, wchar_t& Minus,
1.94 + wchar_t& pow_e, wchar_t& pow_E,
1.95 + wchar_t* digits) {
1.96 + char ndigits[11] = "0123456789";
1.97 + Plus = ct.widen('+');
1.98 + Minus = ct.widen('-');
1.99 + pow_e = ct.widen('e');
1.100 + pow_E = ct.widen('E');
1.101 + ct.widen(ndigits + 0, ndigits + 10, digits);
1.102 +}
1.103 +#endif /* WCHAR_T */
1.104 +
1.105 +/*
1.106 + * __string_to_double is just lifted from atof, the difference being
1.107 + * that we just use '.' for the decimal point, rather than let it
1.108 + * be taken from the current C locale, which of course is not accessible
1.109 + * to us.
1.110 + */
1.111 +#if defined (_STLP_MSVC) || defined (__BORLANDC__) || defined (__ICL)
1.112 +typedef unsigned long uint32;
1.113 +typedef unsigned __int64 uint64;
1.114 +# define ULL(x) x##Ui64
1.115 +#elif defined (__MRC__) || defined (__SC__)
1.116 +typedef unsigned long uint32;
1.117 +# include "uint64.h" //*TY 03/25/2000 - added 64bit math type definition
1.118 +#elif defined (__unix) || defined (__MINGW32__) || defined (N_PLAT_NLM) || \
1.119 + (defined (__DMC__) && (__LONGLONG)) || defined(__SYMBIAN32__)
1.120 +#if defined(__SYMBIAN32__)
1.121 +# include <sys/types.h>
1.122 +#endif
1.123 +typedef uint32_t uint32;
1.124 +typedef uint64_t uint64;
1.125 +# define ULL(x) x##ULL
1.126 +#else
1.127 +# error There should be some unsigned 64-bit integer on the system!
1.128 +#endif
1.129 +
1.130 +// Multiplication of two 64-bit integers, giving a 128-bit result.
1.131 +// Taken from Algorithm M in Knuth section 4.3.1, with the loop
1.132 +// hand-unrolled.
1.133 +static void _Stl_mult64(const uint64 u, const uint64 v,
1.134 + uint64& high, uint64& low) {
1.135 + const uint64 low_mask = ULL(0xffffffff);
1.136 + const uint64 u0 = u & low_mask;
1.137 + const uint64 u1 = u >> 32;
1.138 + const uint64 v0 = v & low_mask;
1.139 + const uint64 v1 = v >> 32;
1.140 +
1.141 + uint64 t = u0 * v0;
1.142 + low = t & low_mask;
1.143 +
1.144 + t = u1 * v0 + (t >> 32);
1.145 + uint64 w1 = t & low_mask;
1.146 + uint64 w2 = t >> 32;
1.147 +
1.148 + uint64 x = u0 * v1 + w1;
1.149 + low += (x & low_mask) << 32;
1.150 + high = u1 * v1 + w2 + (x >> 32);
1.151 +}
1.152 +
1.153 +#define bit11 ULL(0x7ff)
1.154 +#define exponent_mask (bit11 << 52)
1.155 +
1.156 +#if !defined (__GNUC__) || (__GNUC__ != 3) || (__GNUC_MINOR__ != 4) || \
1.157 + (!defined (__CYGWIN__) && !defined (__MINGW32__))
1.158 +//Generate bad code when compiled with -O2 option.
1.159 +inline
1.160 +#endif
1.161 +void _Stl_set_exponent(uint64 &val, uint64 exp)
1.162 +{ val = (val & ~exponent_mask) | ((exp & bit11) << 52); }
1.163 +
1.164 +/* Power of ten fractions for tenscale*/
1.165 +/* The constants are factored so that at most two constants
1.166 + * and two multiplies are needed. Furthermore, one of the constants
1.167 + * is represented exactly - 10**n where 1<= n <= 27.
1.168 + */
1.169 +
1.170 +#if !defined (__SC__) //*TY 03/25/2000 - no native 64bit integer under SCpp
1.171 +static const uint64 _Stl_tenpow[80] = {
1.172 +ULL(0xa000000000000000), /* _Stl_tenpow[0]=(10**1)/(2**4) */
1.173 +ULL(0xc800000000000000), /* _Stl_tenpow[1]=(10**2)/(2**7) */
1.174 +ULL(0xfa00000000000000), /* _Stl_tenpow[2]=(10**3)/(2**10) */
1.175 +ULL(0x9c40000000000000), /* _Stl_tenpow[3]=(10**4)/(2**14) */
1.176 +ULL(0xc350000000000000), /* _Stl_tenpow[4]=(10**5)/(2**17) */
1.177 +ULL(0xf424000000000000), /* _Stl_tenpow[5]=(10**6)/(2**20) */
1.178 +ULL(0x9896800000000000), /* _Stl_tenpow[6]=(10**7)/(2**24) */
1.179 +ULL(0xbebc200000000000), /* _Stl_tenpow[7]=(10**8)/(2**27) */
1.180 +ULL(0xee6b280000000000), /* _Stl_tenpow[8]=(10**9)/(2**30) */
1.181 +ULL(0x9502f90000000000), /* _Stl_tenpow[9]=(10**10)/(2**34) */
1.182 +ULL(0xba43b74000000000), /* _Stl_tenpow[10]=(10**11)/(2**37) */
1.183 +ULL(0xe8d4a51000000000), /* _Stl_tenpow[11]=(10**12)/(2**40) */
1.184 +ULL(0x9184e72a00000000), /* _Stl_tenpow[12]=(10**13)/(2**44) */
1.185 +ULL(0xb5e620f480000000), /* _Stl_tenpow[13]=(10**14)/(2**47) */
1.186 +ULL(0xe35fa931a0000000), /* _Stl_tenpow[14]=(10**15)/(2**50) */
1.187 +ULL(0x8e1bc9bf04000000), /* _Stl_tenpow[15]=(10**16)/(2**54) */
1.188 +ULL(0xb1a2bc2ec5000000), /* _Stl_tenpow[16]=(10**17)/(2**57) */
1.189 +ULL(0xde0b6b3a76400000), /* _Stl_tenpow[17]=(10**18)/(2**60) */
1.190 +ULL(0x8ac7230489e80000), /* _Stl_tenpow[18]=(10**19)/(2**64) */
1.191 +ULL(0xad78ebc5ac620000), /* _Stl_tenpow[19]=(10**20)/(2**67) */
1.192 +ULL(0xd8d726b7177a8000), /* _Stl_tenpow[20]=(10**21)/(2**70) */
1.193 +ULL(0x878678326eac9000), /* _Stl_tenpow[21]=(10**22)/(2**74) */
1.194 +ULL(0xa968163f0a57b400), /* _Stl_tenpow[22]=(10**23)/(2**77) */
1.195 +ULL(0xd3c21bcecceda100), /* _Stl_tenpow[23]=(10**24)/(2**80) */
1.196 +ULL(0x84595161401484a0), /* _Stl_tenpow[24]=(10**25)/(2**84) */
1.197 +ULL(0xa56fa5b99019a5c8), /* _Stl_tenpow[25]=(10**26)/(2**87) */
1.198 +ULL(0xcecb8f27f4200f3a), /* _Stl_tenpow[26]=(10**27)/(2**90) */
1.199 +
1.200 +ULL(0xd0cf4b50cfe20766), /* _Stl_tenpow[27]=(10**55)/(2**183) */
1.201 +ULL(0xd2d80db02aabd62c), /* _Stl_tenpow[28]=(10**83)/(2**276) */
1.202 +ULL(0xd4e5e2cdc1d1ea96), /* _Stl_tenpow[29]=(10**111)/(2**369) */
1.203 +ULL(0xd6f8d7509292d603), /* _Stl_tenpow[30]=(10**139)/(2**462) */
1.204 +ULL(0xd910f7ff28069da4), /* _Stl_tenpow[31]=(10**167)/(2**555) */
1.205 +ULL(0xdb2e51bfe9d0696a), /* _Stl_tenpow[32]=(10**195)/(2**648) */
1.206 +ULL(0xdd50f1996b947519), /* _Stl_tenpow[33]=(10**223)/(2**741) */
1.207 +ULL(0xdf78e4b2bd342cf7), /* _Stl_tenpow[34]=(10**251)/(2**834) */
1.208 +ULL(0xe1a63853bbd26451), /* _Stl_tenpow[35]=(10**279)/(2**927) */
1.209 +ULL(0xe3d8f9e563a198e5), /* _Stl_tenpow[36]=(10**307)/(2**1020) */
1.210 +
1.211 +ULL(0xfd87b5f28300ca0e), /* _Stl_tenpow[37]=(10**-28)/(2**-93) */
1.212 +ULL(0xfb158592be068d2f), /* _Stl_tenpow[38]=(10**-56)/(2**-186) */
1.213 +ULL(0xf8a95fcf88747d94), /* _Stl_tenpow[39]=(10**-84)/(2**-279) */
1.214 +ULL(0xf64335bcf065d37d), /* _Stl_tenpow[40]=(10**-112)/(2**-372) */
1.215 +ULL(0xf3e2f893dec3f126), /* _Stl_tenpow[41]=(10**-140)/(2**-465) */
1.216 +ULL(0xf18899b1bc3f8ca2), /* _Stl_tenpow[42]=(10**-168)/(2**-558) */
1.217 +ULL(0xef340a98172aace5), /* _Stl_tenpow[43]=(10**-196)/(2**-651) */
1.218 +ULL(0xece53cec4a314ebe), /* _Stl_tenpow[44]=(10**-224)/(2**-744) */
1.219 +ULL(0xea9c227723ee8bcb), /* _Stl_tenpow[45]=(10**-252)/(2**-837) */
1.220 +ULL(0xe858ad248f5c22ca), /* _Stl_tenpow[46]=(10**-280)/(2**-930) */
1.221 +ULL(0xe61acf033d1a45df), /* _Stl_tenpow[47]=(10**-308)/(2**-1023) */
1.222 +ULL(0xe3e27a444d8d98b8), /* _Stl_tenpow[48]=(10**-336)/(2**-1116) */
1.223 +ULL(0xe1afa13afbd14d6e) /* _Stl_tenpow[49]=(10**-364)/(2**-1209) */
1.224 +
1.225 +#else //*TY 03/20/2000 - added support for SCpp which lacks native 64bit integer type
1.226 +static const UnsignedWide _Stl_tenpow[80] = {
1.227 +ULL2(0xa0000000,0x00000000), /* _Stl_tenpow[0]=(10**1)/(2**4) */
1.228 +ULL2(0xc8000000,0x00000000), /* _Stl_tenpow[1]=(10**2)/(2**7) */
1.229 +ULL2(0xfa000000,0x00000000), /* _Stl_tenpow[2]=(10**3)/(2**10) */
1.230 +ULL2(0x9c400000,0x00000000), /* _Stl_tenpow[3]=(10**4)/(2**14) */
1.231 +ULL2(0xc3500000,0x00000000), /* _Stl_tenpow[4]=(10**5)/(2**17) */
1.232 +ULL2(0xf4240000,0x00000000), /* _Stl_tenpow[5]=(10**6)/(2**20) */
1.233 +ULL2(0x98968000,0x00000000), /* _Stl_tenpow[6]=(10**7)/(2**24) */
1.234 +ULL2(0xbebc2000,0x00000000), /* _Stl_tenpow[7]=(10**8)/(2**27) */
1.235 +ULL2(0xee6b2800,0x00000000), /* _Stl_tenpow[8]=(10**9)/(2**30) */
1.236 +ULL2(0x9502f900,0x00000000), /* _Stl_tenpow[9]=(10**10)/(2**34) */
1.237 +ULL2(0xba43b740,0x00000000), /* _Stl_tenpow[10]=(10**11)/(2**37) */
1.238 +ULL2(0xe8d4a510,0x00000000), /* _Stl_tenpow[11]=(10**12)/(2**40) */
1.239 +ULL2(0x9184e72a,0x00000000), /* _Stl_tenpow[12]=(10**13)/(2**44) */
1.240 +ULL2(0xb5e620f4,0x80000000), /* _Stl_tenpow[13]=(10**14)/(2**47) */
1.241 +ULL2(0xe35fa931,0xa0000000), /* _Stl_tenpow[14]=(10**15)/(2**50) */
1.242 +ULL2(0x8e1bc9bf,0x04000000), /* _Stl_tenpow[15]=(10**16)/(2**54) */
1.243 +ULL2(0xb1a2bc2e,0xc5000000), /* _Stl_tenpow[16]=(10**17)/(2**57) */
1.244 +ULL2(0xde0b6b3a,0x76400000), /* _Stl_tenpow[17]=(10**18)/(2**60) */
1.245 +ULL2(0x8ac72304,0x89e80000), /* _Stl_tenpow[18]=(10**19)/(2**64) */
1.246 +ULL2(0xad78ebc5,0xac620000), /* _Stl_tenpow[19]=(10**20)/(2**67) */
1.247 +ULL2(0xd8d726b7,0x177a8000), /* _Stl_tenpow[20]=(10**21)/(2**70) */
1.248 +ULL2(0x87867832,0x6eac9000), /* _Stl_tenpow[21]=(10**22)/(2**74) */
1.249 +ULL2(0xa968163f,0x0a57b400), /* _Stl_tenpow[22]=(10**23)/(2**77) */
1.250 +ULL2(0xd3c21bce,0xcceda100), /* _Stl_tenpow[23]=(10**24)/(2**80) */
1.251 +ULL2(0x84595161,0x401484a0), /* _Stl_tenpow[24]=(10**25)/(2**84) */
1.252 +ULL2(0xa56fa5b9,0x9019a5c8), /* _Stl_tenpow[25]=(10**26)/(2**87) */
1.253 +ULL2(0xcecb8f27,0xf4200f3a), /* _Stl_tenpow[26]=(10**27)/(2**90) */
1.254 +
1.255 +ULL2(0xd0cf4b50,0xcfe20766), /* _Stl_tenpow[27]=(10**55)/(2**183) */
1.256 +ULL2(0xd2d80db0,0x2aabd62c), /* _Stl_tenpow[28]=(10**83)/(2**276) */
1.257 +ULL2(0xd4e5e2cd,0xc1d1ea96), /* _Stl_tenpow[29]=(10**111)/(2**369) */
1.258 +ULL2(0xd6f8d750,0x9292d603), /* _Stl_tenpow[30]=(10**139)/(2**462) */
1.259 +ULL2(0xd910f7ff,0x28069da4), /* _Stl_tenpow[31]=(10**167)/(2**555) */
1.260 +ULL2(0xdb2e51bf,0xe9d0696a), /* _Stl_tenpow[32]=(10**195)/(2**648) */
1.261 +ULL2(0xdd50f199,0x6b947519), /* _Stl_tenpow[33]=(10**223)/(2**741) */
1.262 +ULL2(0xdf78e4b2,0xbd342cf7), /* _Stl_tenpow[34]=(10**251)/(2**834) */
1.263 +ULL2(0xe1a63853,0xbbd26451), /* _Stl_tenpow[35]=(10**279)/(2**927) */
1.264 +ULL2(0xe3d8f9e5,0x63a198e5), /* _Stl_tenpow[36]=(10**307)/(2**1020) */
1.265 +
1.266 +ULL2(0xfd87b5f2,0x8300ca0e), /* _Stl_tenpow[37]=(10**-28)/(2**-93) */
1.267 +ULL2(0xfb158592,0xbe068d2f), /* _Stl_tenpow[38]=(10**-56)/(2**-186) */
1.268 +ULL2(0xf8a95fcf,0x88747d94), /* _Stl_tenpow[39]=(10**-84)/(2**-279) */
1.269 +ULL2(0xf64335bc,0xf065d37d), /* _Stl_tenpow[40]=(10**-112)/(2**-372) */
1.270 +ULL2(0xf3e2f893,0xdec3f126), /* _Stl_tenpow[41]=(10**-140)/(2**-465) */
1.271 +ULL2(0xf18899b1,0xbc3f8ca2), /* _Stl_tenpow[42]=(10**-168)/(2**-558) */
1.272 +ULL2(0xef340a98,0x172aace5), /* _Stl_tenpow[43]=(10**-196)/(2**-651) */
1.273 +ULL2(0xece53cec,0x4a314ebe), /* _Stl_tenpow[44]=(10**-224)/(2**-744) */
1.274 +ULL2(0xea9c2277,0x23ee8bcb), /* _Stl_tenpow[45]=(10**-252)/(2**-837) */
1.275 +ULL2(0xe858ad24,0x8f5c22ca), /* _Stl_tenpow[46]=(10**-280)/(2**-930) */
1.276 +ULL2(0xe61acf03,0x3d1a45df), /* _Stl_tenpow[47]=(10**-308)/(2**-1023) */
1.277 +ULL2(0xe3e27a44,0x4d8d98b8), /* _Stl_tenpow[48]=(10**-336)/(2**-1116) */
1.278 +ULL2(0xe1afa13a,0xfbd14d6e) /* _Stl_tenpow[49]=(10**-364)/(2**-1209) */
1.279 +#endif
1.280 +};
1.281 +
1.282 +static const short _Stl_twoexp[80] = {
1.283 +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,
1.284 +183,276,369,462,555,648,741,834,927,1020,
1.285 +-93,-186,-279,-372,-465,-558,-651,-744,-837,-930,-1023,-1116,-1209
1.286 +};
1.287 +
1.288 +#define TEN_1 0 /* offset to 10 ** 1 */
1.289 +#define TEN_27 26 /* offset to 10 ** 27 */
1.290 +#define TEN_M28 37 /* offset to 10 ** -28 */
1.291 +#define NUM_HI_P 11
1.292 +#define NUM_HI_N 13
1.293 +
1.294 +#define _Stl_HIBITULL (ULL(1) << 63)
1.295 +
1.296 +static void _Stl_norm_and_round(uint64& p, int& norm, uint64 prodhi, uint64 prodlo) {
1.297 + norm = 0;
1.298 + if ((prodhi & _Stl_HIBITULL) == 0) {
1.299 + /* leading bit is a zero
1.300 + * may have to normalize
1.301 + */
1.302 + if ((prodhi == ~_Stl_HIBITULL) &&
1.303 + ((prodlo >> 62) == 0x3)) { /* normalization followed by round
1.304 + * would cause carry to create
1.305 + * extra bit, so don't normalize
1.306 + */
1.307 + p = _Stl_HIBITULL;
1.308 + return;
1.309 + }
1.310 + p = (prodhi << 1) | (prodlo >> 63); /* normalize */
1.311 + norm = 1;
1.312 + prodlo <<= 1;
1.313 + }
1.314 + else {
1.315 + p = prodhi;
1.316 + }
1.317 +
1.318 + if ((prodlo & _Stl_HIBITULL) != 0) { /* first guard bit a one */ //*TY 03/25/2000 - added explicit comparison to zero to avoid reliance to the implicit conversion from uint64 to bool
1.319 +#if !defined (__SC__) //*TY 03/25/2000 -
1.320 + if (((p & 0x1) != 0) ||
1.321 + prodlo != _Stl_HIBITULL ) { /* not borderline for round to even */
1.322 +#else //*TY 03/25/2000 - added workaround for SCpp compiler
1.323 + bool b1 = ((p & 0x1) != 0);
1.324 + if (b1 || prodlo != _Stl_HIBITULL) { //*TY 03/25/2000 - SCpp confuses on this particular original boolean expression
1.325 +#endif //*TY 03/25/2000 -
1.326 + /* round */
1.327 + ++p;
1.328 + if (p == 0)
1.329 + ++p;
1.330 + }
1.331 + }
1.332 +
1.333 + return;
1.334 +}
1.335 +
1.336 +// Convert a 64-bitb fraction * 10^exp to a 64-bit fraction * 2^bexp.
1.337 +// p: 64-bit fraction
1.338 +// exp: base-10 exponent
1.339 +// bexp: base-2 exponent (output parameter)
1.340 +static void _Stl_tenscale(uint64& p, int exp, int& bexp) {
1.341 + uint64 prodhi, prodlo; /* 128b product */
1.342 + int exp_hi, exp_lo; /* exp = exp_hi*32 + exp_lo */
1.343 + int hi, lo, tlo, thi; /* offsets in power of ten table */
1.344 + int norm; /* number of bits of normalization */
1.345 + int num_hi; /* number of high exponent powers */
1.346 +
1.347 + bexp = 0;
1.348 + if (exp > 0) { /* split exponent */
1.349 + exp_lo = exp;
1.350 + exp_hi = 0;
1.351 + if (exp_lo > 27) {
1.352 + exp_lo++;
1.353 + while (exp_lo > 27) {
1.354 + exp_hi++;
1.355 + exp_lo -= 28;
1.356 + }
1.357 + }
1.358 + tlo = TEN_1;
1.359 + thi = TEN_27;
1.360 + num_hi = NUM_HI_P;
1.361 + }
1.362 + else if (exp < 0) {
1.363 + exp_lo = exp;
1.364 + exp_hi = 0;
1.365 + while (exp_lo < 0) {
1.366 + exp_hi++;
1.367 + exp_lo += 28;
1.368 + }
1.369 + tlo = TEN_1;
1.370 + thi = TEN_M28;
1.371 + num_hi = NUM_HI_N;
1.372 + }
1.373 + else { /* no scaling needed */
1.374 + return;
1.375 + }
1.376 + while (exp_hi) { /* scale */
1.377 + hi = (min) (exp_hi, num_hi); /* only a few large powers of 10 */
1.378 + exp_hi -= hi; /* could iterate in extreme case */
1.379 + hi += thi-1;
1.380 + _Stl_mult64(p, _Stl_tenpow[hi], prodhi, prodlo);
1.381 + _Stl_norm_and_round(p, norm, prodhi, prodlo);
1.382 + bexp += _Stl_twoexp[hi] - norm;
1.383 + }
1.384 + if (exp_lo) {
1.385 + lo = tlo + exp_lo -1;
1.386 + _Stl_mult64(p, _Stl_tenpow[lo], prodhi, prodlo);
1.387 + _Stl_norm_and_round(p, norm, prodhi, prodlo);
1.388 + bexp += _Stl_twoexp[lo] - norm;
1.389 + }
1.390 +
1.391 + return;
1.392 +}
1.393 +
1.394 +// First argument is a buffer of values from 0 to 9, NOT ascii.
1.395 +// Second argument is number of digits in buffer, 1 <= digits <= 17.
1.396 +// Third argument is base-10 exponent.
1.397 +
1.398 +#if defined (__SC__) || defined (__MRC__)
1.399 +
1.400 +//*TY 04/06/2000 - powermac's 68K emulator utilizes apple's SANE floating point, which is not compatible with IEEE format.
1.401 +_STLP_MOVE_TO_STD_NAMESPACE
1.402 +_STLP_END_NAMESPACE
1.403 +
1.404 +# include <fp.h>
1.405 +
1.406 +_STLP_BEGIN_NAMESPACE
1.407 +_STLP_MOVE_TO_PRIV_NAMESPACE
1.408 +
1.409 +static inline double _Stl_atod(char *buffer, int ndigit, int dexp) {
1.410 + decimal d; // ref. inside macintosh powerpc numerics p.9-13
1.411 +
1.412 + d.sgn = 0;
1.413 + d.exp = dexp;
1.414 + d.sig.length = ndigit;
1.415 + for (int i = 0; i < ndigit; ++i) {
1.416 + d.sig.text[i] = buffer[i] + '0';
1.417 + }
1.418 + return dec2num(&d);
1.419 +}
1.420 +
1.421 +#else /* IEEE representation */
1.422 +
1.423 +# if !defined (__linux__)
1.424 +static double _Stl_atod(char *buffer, int ndigit, int dexp) {
1.425 + uint64 value; /* Value develops as follows:
1.426 + * 1) decimal digits as an integer
1.427 + * 2) left adjusted fraction
1.428 + * 3) right adjusted fraction
1.429 + * 4) exponent and fraction
1.430 + */
1.431 +
1.432 + uint32 guard; /* First guard bit */
1.433 + uint64 rest; /* Remaining guard bits */
1.434 +
1.435 + int bexp; /* binary exponent */
1.436 + int nzero; /* number of non-zero bits */
1.437 + int sexp; /* scaling exponent */
1.438 +
1.439 + char *bufferend; /* pointer to char after last digit */
1.440 +
1.441 + /* Check for zero and treat it as a special case */
1.442 + if (buffer == 0){
1.443 + return 0.0;
1.444 + }
1.445 +
1.446 + /* Convert the decimal digits to a binary integer. */
1.447 +
1.448 + bufferend = buffer + ndigit;
1.449 + value = 0;
1.450 +
1.451 + while (buffer < bufferend) {
1.452 + value *= 10;
1.453 + value += *buffer++;
1.454 + }
1.455 +
1.456 + /* Check for zero and treat it as a special case */
1.457 + if (value == 0) {
1.458 + return 0.0;
1.459 + }
1.460 +
1.461 + /* Normalize value */
1.462 + bexp = 64; /* convert from 64b int to fraction */
1.463 +
1.464 + /* Count number of non-zeroes in value */
1.465 + nzero = 0;
1.466 + if ((value >> 32) != 0) { nzero = 32; } //*TY 03/25/2000 - added explicit comparison to zero to avoid uint64 to bool conversion operator
1.467 + if ((value >> (16 + nzero)) != 0) { nzero += 16; }
1.468 + if ((value >> ( 8 + nzero)) != 0) { nzero += 8; }
1.469 + if ((value >> ( 4 + nzero)) != 0) { nzero += 4; }
1.470 + if ((value >> ( 2 + nzero)) != 0) { nzero += 2; }
1.471 + if ((value >> ( 1 + nzero)) != 0) { nzero += 1; }
1.472 + if ((value >> ( nzero)) != 0) { nzero += 1; }
1.473 +
1.474 + /* Normalize */
1.475 + value <<= /*(uint64)*/ (64 - nzero); //*TY 03/25/2000 - removed extraneous cast to uint64
1.476 + bexp -= 64 - nzero;
1.477 +
1.478 + /* At this point we have a 64b fraction and a binary exponent
1.479 + * but have yet to incorporate the decimal exponent.
1.480 + */
1.481 +
1.482 + /* multiply by 10^dexp */
1.483 + _Stl_tenscale(value, dexp, sexp);
1.484 + bexp += sexp;
1.485 +
1.486 + if (bexp <= -1022) { /* HI denorm or underflow */
1.487 + bexp += 1022;
1.488 + if (bexp < -53) { /* guaranteed underflow */
1.489 + value = 0;
1.490 + }
1.491 + else { /* denorm or possible underflow */
1.492 + int lead0 = 12 - bexp; /* 12 sign and exponent bits */
1.493 +
1.494 + /* we must special case right shifts of more than 63 */
1.495 + if (lead0 > 64) {
1.496 + rest = value;
1.497 + guard = 0;
1.498 + value = 0;
1.499 + }
1.500 + else if (lead0 == 64) {
1.501 + rest = value & ((ULL(1)<< 63)-1);
1.502 +#if !defined(__SC__)
1.503 + guard = (uint32) ((value>> 63) & 1 );
1.504 +#else
1.505 + guard = to_ulong((value>> 63) & 1 ); //*TY 03/25/2000 - use member function instead of problematic conversion operator utilization
1.506 +#endif
1.507 + value = 0;
1.508 + }
1.509 + else {
1.510 + rest = value & (((ULL(1) << lead0)-1)-1);
1.511 +#if !defined(__SC__)
1.512 + guard = (uint32) (((value>> lead0)-1) & 1);
1.513 +#else //*TY 03/25/2000 -
1.514 + guard = to_ulong(((value>> lead0)-1) & 1);
1.515 +#endif //*TY 03/25/2000 -
1.516 + value >>= /*(uint64)*/ lead0; /* exponent is zero */
1.517 + }
1.518 +
1.519 + /* Round */
1.520 + if (guard && ((value & 1) || rest) ) {
1.521 + ++value;
1.522 + if (value == (ULL(1) << 52)) { /* carry created normal number */
1.523 + value = 0;
1.524 + _Stl_set_exponent(value, 1);
1.525 + }
1.526 + }
1.527 + }
1.528 + }
1.529 + else { /* not zero or denorm */
1.530 + /* Round to 53 bits */
1.531 + rest = value & (1<<10)-1;
1.532 + value >>= 10;
1.533 +#if !defined(__SC__)
1.534 + guard = (uint32) value & 1;
1.535 +#else //*TY 03/25/2000 -
1.536 + guard = to_ulong(value & 1);
1.537 +#endif
1.538 + value >>= 1;
1.539 +
1.540 + /* value&1 guard rest Action
1.541 + *
1.542 + * dc 0 dc none
1.543 + * 1 1 dc round
1.544 + * 0 1 0 none
1.545 + * 0 1 !=0 round
1.546 + */
1.547 + if (guard) {
1.548 + if (((value&1)!=0) || (rest!=0)) {
1.549 + ++value; /* round */
1.550 + if ((value >> 53) != 0) { /* carry all the way across */
1.551 + value >>= 1; /* renormalize */
1.552 + ++bexp;
1.553 + }
1.554 + }
1.555 + }
1.556 + /*
1.557 + * Check for overflow
1.558 + * IEEE Double Precision Format
1.559 + * (From Table 7-8 of Kane and Heinrich)
1.560 + *
1.561 + * Fraction bits 52
1.562 + * Emax +1023
1.563 + * Emin -1022
1.564 + * Exponent bias +1023
1.565 + * Exponent bits 11
1.566 + * Integer bit hidden
1.567 + * Total width in bits 64
1.568 + */
1.569 +
1.570 + if (bexp > 1024) { /* overflow */
1.571 + return numeric_limits<double>::infinity();
1.572 + }
1.573 + else { /* value is normal */
1.574 + value &= ~(ULL(1) << 52); /* hide hidden bit */
1.575 + _Stl_set_exponent(value, bexp + 1022); /* add bias */
1.576 + }
1.577 + }
1.578 +
1.579 + _STLP_STATIC_ASSERT(sizeof(value) == sizeof(double))
1.580 + return *((double *) &value);
1.581 +}
1.582 +
1.583 +# else // __linux__
1.584 +
1.585 +static double _Stl_atod(char *buffer, int ndigit, int dexp) {
1.586 + ieee754_double v;
1.587 +
1.588 + char *bufferend; /* pointer to char after last digit */
1.589 +
1.590 + /* Check for zero and treat it as a special case */
1.591 +
1.592 + if (buffer == 0) {
1.593 + return 0.0;
1.594 + }
1.595 +
1.596 + /* Convert the decimal digits to a binary integer. */
1.597 +
1.598 + bufferend = buffer + ndigit;
1.599 + _ll vv;
1.600 + vv.i64 = 0L;
1.601 +
1.602 + while (buffer < bufferend) {
1.603 + vv.i64 *= 10;
1.604 + vv.i64 += *buffer++;
1.605 + }
1.606 +
1.607 + /* Check for zero and treat it as a special case */
1.608 + if (vv.i64 == 0){
1.609 + return 0.0;
1.610 + }
1.611 +
1.612 + /* Normalize value */
1.613 + int bexp = 64; /* convert from 64b int to fraction */
1.614 +
1.615 + /* Count number of non-zeroes in value */
1.616 + int nzero = 0;
1.617 + if ((vv.i64 >> 32) !=0 ) { nzero = 32; } //*TY 03/25/2000 - added explicit comparison to zero to avoid uint64 to bool conversion operator
1.618 + if ((vv.i64 >> (16 + nzero)) != 0) { nzero += 16; }
1.619 + if ((vv.i64 >> ( 8 + nzero)) != 0) { nzero += 8; }
1.620 + if ((vv.i64 >> ( 4 + nzero)) != 0) { nzero += 4; }
1.621 + if ((vv.i64 >> ( 2 + nzero)) != 0) { nzero += 2; }
1.622 + if ((vv.i64 >> ( 1 + nzero)) != 0) { nzero += 1; }
1.623 + if ((vv.i64 >> ( nzero)) != 0) { nzero += 1; }
1.624 +
1.625 + /* Normalize */
1.626 + nzero = 64 - nzero;
1.627 + vv.i64 <<= nzero; //*TY 03/25/2000 - removed extraneous cast to uint64
1.628 + bexp -= nzero;
1.629 +
1.630 + /* At this point we have a 64b fraction and a binary exponent
1.631 + * but have yet to incorporate the decimal exponent.
1.632 + */
1.633 +
1.634 + /* multiply by 10^dexp */
1.635 + int sexp;
1.636 + _Stl_tenscale(vv.i64, dexp, sexp);
1.637 + bexp += sexp;
1.638 +
1.639 + if (bexp <= -1022) { /* HI denorm or underflow */
1.640 + bexp += 1022;
1.641 + if (bexp < -53) { /* guaranteed underflow */
1.642 + vv.i64 = 0;
1.643 + }
1.644 + else { /* denorm or possible underflow */
1.645 + int lead0;
1.646 + uint64_t rest;
1.647 + uint32_t guard;
1.648 +
1.649 + lead0 = 12-bexp; /* 12 sign and exponent bits */
1.650 +
1.651 + /* we must special case right shifts of more than 63 */
1.652 + if (lead0 > 64) {
1.653 + rest = vv.i64;
1.654 + guard = 0;
1.655 + vv.i64 = 0;
1.656 + }
1.657 + else if (lead0 == 64) {
1.658 + rest = vv.i64 & ((ULL(1) << 63)-1);
1.659 +#if !defined(__SC__)
1.660 + guard = (uint32) ((vv.i64 >> 63) & 1 );
1.661 +#else
1.662 + guard = to_ulong((vv.i64 >> 63) & 1 ); //*TY 03/25/2000 - use member function instead of problematic conversion operator utilization
1.663 +#endif
1.664 + vv.i64 = 0;
1.665 + }
1.666 + else {
1.667 + rest = vv.i64 & (((ULL(1) << lead0)-1)-1);
1.668 +#if !defined(__SC__)
1.669 + guard = (uint32) (((vv.i64 >> lead0)-1) & 1);
1.670 +#else //*TY 03/25/2000 -
1.671 + guard = to_ulong(((vv.i64 >> lead0)-1) & 1);
1.672 +#endif //*TY 03/25/2000 -
1.673 + vv.i64 >>= /*(uint64)*/ lead0; /* exponent is zero */
1.674 + }
1.675 +
1.676 + /* Round */
1.677 + if (guard && ( (vv.i64 & 1) || rest)) {
1.678 + vv.i64++;
1.679 + if (vv.i64 == (ULL(1) << 52)) { /* carry created normal number */
1.680 + v.ieee.mantissa0 = 0;
1.681 + v.ieee.mantissa1 = 0;
1.682 + v.ieee.negative = 0;
1.683 + v.ieee.exponent = 1;
1.684 + return v.d;
1.685 + }
1.686 + }
1.687 + }
1.688 + }
1.689 + else { /* not zero or denorm */
1.690 + /* Round to 53 bits */
1.691 + uint64_t rest = vv.i64 & (1<<10)-1;
1.692 + vv.i64 >>= 10;
1.693 +#if !defined(__SC__)
1.694 + uint32_t guard = (uint32) vv.i64 & 1;
1.695 +#else //*TY 03/25/2000 -
1.696 + uint32_t guard = to_ulong(vv.i64 & 1);
1.697 +#endif
1.698 + vv.i64 >>= 1;
1.699 +
1.700 + /* value&1 guard rest Action
1.701 + *
1.702 + * dc 0 dc none
1.703 + * 1 1 dc round
1.704 + * 0 1 0 none
1.705 + * 0 1 !=0 round
1.706 + */
1.707 + if (guard) {
1.708 + if (((vv.i64&1)!=0) || (rest!=0)) {
1.709 + vv.i64++; /* round */
1.710 + if ((vv.i64>>53)!=0) { /* carry all the way across */
1.711 + vv.i64 >>= 1; /* renormalize */
1.712 + ++bexp;
1.713 + }
1.714 + }
1.715 + }
1.716 + /*
1.717 + * Check for overflow
1.718 + * IEEE Double Precision Format
1.719 + * (From Table 7-8 of Kane and Heinrich)
1.720 + *
1.721 + * Fraction bits 52
1.722 + * Emax +1023
1.723 + * Emin -1022
1.724 + * Exponent bias +1023
1.725 + * Exponent bits 11
1.726 + * Integer bit hidden
1.727 + * Total width in bits 64
1.728 + */
1.729 +
1.730 + if (bexp > 1024) { /* overflow */
1.731 + return numeric_limits<double>::infinity();
1.732 + }
1.733 + else { /* value is normal */
1.734 + vv.i64 &= ~(ULL(1) << 52); /* hide hidden bit */
1.735 + v.ieee.mantissa0 = vv.i32.hi;
1.736 + v.ieee.mantissa1 = vv.i32.lo;
1.737 + v.ieee.negative = 0;
1.738 + v.ieee.exponent = bexp + 1022;
1.739 + return v.d;
1.740 + }
1.741 + }
1.742 +
1.743 + v.ieee.mantissa0 = vv.i32.hi;
1.744 + v.ieee.mantissa1 = vv.i32.lo;
1.745 + v.ieee.negative = 0;
1.746 + v.ieee.exponent = 0;
1.747 +
1.748 + return v.d;
1.749 +}
1.750 +# endif // __linux__
1.751 +
1.752 +#endif
1.753 +
1.754 +static double _Stl_string_to_double(const char *s) {
1.755 + const int max_digits = 17;
1.756 + unsigned c;
1.757 + unsigned Negate, decimal_point;
1.758 + char *d;
1.759 + int exp;
1.760 + double x;
1.761 + int dpchar;
1.762 + char digits[max_digits];
1.763 +
1.764 + // Skip leading whitespace, if any.
1.765 + const ctype<char>& ct = use_facet<ctype<char> >(locale::classic());
1.766 + while (c = *s++, ct.is(ctype_base::space, char(c))) {}
1.767 +
1.768 + /* process sign */
1.769 + Negate = 0;
1.770 + if (c == '+') {
1.771 + c = *s++;
1.772 + }
1.773 + else if (c == '-') {
1.774 + Negate = 1;
1.775 + c = *s++;
1.776 + }
1.777 + d = digits;
1.778 + dpchar = '.' - '0';
1.779 + decimal_point = 0;
1.780 + exp = 0;
1.781 + for (;;) {
1.782 + c -= '0';
1.783 + if (c < 10) {
1.784 + if (d == digits + max_digits) {
1.785 + /* ignore more than 17 digits, but adjust exponent */
1.786 + exp += (decimal_point ^ 1);
1.787 + }
1.788 + else {
1.789 + if (c == 0 && d == digits) {
1.790 + /* ignore leading zeros */
1.791 + }
1.792 + else {
1.793 + *d++ = (char) c;
1.794 + }
1.795 + exp -= decimal_point;
1.796 + }
1.797 + }
1.798 + else if (c == (unsigned int) dpchar && !decimal_point) { /* INTERNATIONAL */
1.799 + decimal_point = 1;
1.800 + }
1.801 + else {
1.802 + break;
1.803 + }
1.804 + c = *s++;
1.805 + }
1.806 + /* strtod cant return until it finds the end of the exponent */
1.807 + if (d == digits) {
1.808 + return 0.0;
1.809 + }
1.810 +
1.811 + if (c == 'e'-'0' || c == 'E'-'0') {
1.812 + register unsigned negate_exp = 0;
1.813 + register int e = 0;
1.814 + c = *s++;
1.815 + if (c == '+' || c == ' ') {
1.816 + c = *s++;
1.817 + }
1.818 + else if (c == '-') {
1.819 + negate_exp = 1;
1.820 + c = *s++;
1.821 + }
1.822 + if (c -= '0', c < 10) {
1.823 + do {
1.824 + if (e <= 340)
1.825 + e = e * 10 + (int)c;
1.826 + else break;
1.827 + c = *s++;
1.828 + }
1.829 + while (c -= '0', c < 10);
1.830 + if (negate_exp) {
1.831 + e = -e;
1.832 + }
1.833 + if (e < -340 || e > 340)
1.834 + exp = e;
1.835 + else
1.836 + exp += e;
1.837 + }
1.838 + }
1.839 +
1.840 + if (exp < -340) {
1.841 + x = 0;
1.842 + }
1.843 + else if (exp > 308) {
1.844 + x = numeric_limits<double>::infinity();
1.845 + }
1.846 + else {
1.847 + /* let _Stl_atod diagnose under- and over-flows */
1.848 + /* if the input was == 0.0, we have already returned,
1.849 + so retval of +-Inf signals OVERFLOW, 0.0 UNDERFLOW
1.850 + */
1.851 + x = _Stl_atod(digits, (int)(d - digits), exp);
1.852 + }
1.853 + if (Negate) {
1.854 + x = -x;
1.855 + }
1.856 + return x;
1.857 +}
1.858 +
1.859 +
1.860 +#if !defined (_STLP_NO_LONG_DOUBLE)
1.861 +/*
1.862 + * __string_to_long_double is just lifted from atold, the difference being
1.863 + * that we just use '.' for the decimal point, rather than let it
1.864 + * be taken from the current C locale, which of course is not accessible
1.865 + * to us.
1.866 + */
1.867 +
1.868 +static long double
1.869 +_Stl_string_to_long_double(const char * s) {
1.870 + const int max_digits = 34;
1.871 + register unsigned c;
1.872 + register unsigned Negate, decimal_point;
1.873 + register char *d;
1.874 + register int exp;
1.875 + long double x;
1.876 + register int dpchar;
1.877 + char digits[max_digits];
1.878 +
1.879 + const ctype<char>& ct = use_facet<ctype<char> >(locale::classic());
1.880 + while (c = *s++, ct.is(ctype_base::space, char(c)))
1.881 + ;
1.882 +
1.883 + /* process sign */
1.884 + Negate = 0;
1.885 + if (c == '+') {
1.886 + c = *s++;
1.887 + }
1.888 + else if (c == '-') {
1.889 + Negate = 1;
1.890 + c = *s++;
1.891 + }
1.892 +
1.893 + d = digits;
1.894 + dpchar = '.' - '0';
1.895 + decimal_point = 0;
1.896 + exp = 0;
1.897 +
1.898 + for (;;) {
1.899 + c -= '0';
1.900 + if (c < 10) {
1.901 + if (d == digits+max_digits) {
1.902 + /* ignore more than 34 digits, but adjust exponent */
1.903 + exp += (decimal_point ^ 1);
1.904 + }
1.905 + else {
1.906 + if (c == 0 && d == digits) {
1.907 + /* ignore leading zeros */
1.908 + ;
1.909 + }
1.910 + else {
1.911 + *d++ = (char)c;
1.912 + }
1.913 + exp -= decimal_point;
1.914 + }
1.915 + }
1.916 + else if ((char)c == dpchar && !decimal_point) { /* INTERNATIONAL */
1.917 + decimal_point = 1;
1.918 + }
1.919 + else {
1.920 + break;
1.921 + }
1.922 + c = *s++;
1.923 + } /* for */
1.924 +
1.925 + if (d == digits) {
1.926 + return 0.0L;
1.927 + }
1.928 + if (c == 'e'-'0' || c == 'E'-'0') {
1.929 + register unsigned negate_exp = 0;
1.930 + register int e = 0;
1.931 + c = *s++;
1.932 + if (c == '+' || c == ' ') {
1.933 + c = *s++;
1.934 + }
1.935 + else if (c == '-') {
1.936 + negate_exp = 1;
1.937 + c = *s++;
1.938 + }
1.939 + if (c -= '0', c < 10) {
1.940 + do {
1.941 + if (e <= 340)
1.942 + e = e * 10 + c;
1.943 + else break;
1.944 + c = *s++;
1.945 + }
1.946 + while (c -= '0', c < 10);
1.947 + if (negate_exp) {
1.948 + e = -e;
1.949 + }
1.950 + if (e < -(323+max_digits) || e > 308)
1.951 + exp = e;
1.952 + else
1.953 + exp += e;
1.954 + }
1.955 + }
1.956 +
1.957 + if (exp < -(324+max_digits)) {
1.958 + x = 0;
1.959 + }
1.960 + else if (exp > 308) {
1.961 + x = numeric_limits<long double>::infinity();
1.962 + }
1.963 + else {
1.964 + /* let _Stl_atod diagnose under- and over-flows */
1.965 + /* if the input was == 0.0, we have already returned,
1.966 + so retval of +-Inf signals OVERFLOW, 0.0 UNDERFLOW
1.967 + */
1.968 +
1.969 + // x = _Stl_atod (digits, (int)(d - digits), exp); // TEMPORARY!!:1
1.970 + double tmp = _Stl_atod (digits, (int)(d - digits), exp); // TEMPORARY!!:1
1.971 + x = tmp == numeric_limits<double>::infinity()
1.972 + ? numeric_limits<long double>::infinity()
1.973 + : tmp;
1.974 + }
1.975 +
1.976 + if (Negate) {
1.977 + x = -x;
1.978 + }
1.979 +
1.980 + return x;
1.981 +}
1.982 +#endif
1.983 +
1.984 +void _STLP_DECLSPEC _STLP_CALL
1.985 +__string_to_float(const __iostring& v, float& val)
1.986 +{ val = (float)_Stl_string_to_double(v.c_str()); }
1.987 +
1.988 +void _STLP_DECLSPEC _STLP_CALL
1.989 +__string_to_float(const __iostring& v, double& val)
1.990 +{ val = _Stl_string_to_double(v.c_str()); }
1.991 +
1.992 +#if !defined (_STLP_NO_LONG_DOUBLE)
1.993 +void _STLP_DECLSPEC _STLP_CALL
1.994 +__string_to_float(const __iostring& v, long double& val)
1.995 +{ val = _Stl_string_to_long_double(v.c_str()); }
1.996 +#endif
1.997 +
1.998 +_STLP_MOVE_TO_STD_NAMESPACE
1.999 +_STLP_END_NAMESPACE
1.1000 +
1.1001 +// Local Variables:
1.1002 +// mode:C++
1.1003 +// End: