1f9f848faSopenharmony_ci/**************************************************************** 2f9f848faSopenharmony_ci 3f9f848faSopenharmony_ciThe author of this software is David M. Gay. 4f9f848faSopenharmony_ci 5f9f848faSopenharmony_ciCopyright (C) 1998-2001 by Lucent Technologies 6f9f848faSopenharmony_ciAll Rights Reserved 7f9f848faSopenharmony_ci 8f9f848faSopenharmony_ciPermission to use, copy, modify, and distribute this software and 9f9f848faSopenharmony_ciits documentation for any purpose and without fee is hereby 10f9f848faSopenharmony_cigranted, provided that the above copyright notice appear in all 11f9f848faSopenharmony_cicopies and that both that the copyright notice and this 12f9f848faSopenharmony_cipermission notice and warranty disclaimer appear in supporting 13f9f848faSopenharmony_cidocumentation, and that the name of Lucent or any of its entities 14f9f848faSopenharmony_cinot be used in advertising or publicity pertaining to 15f9f848faSopenharmony_cidistribution of the software without specific, written prior 16f9f848faSopenharmony_cipermission. 17f9f848faSopenharmony_ci 18f9f848faSopenharmony_ciLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 19f9f848faSopenharmony_ciINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 20f9f848faSopenharmony_ciIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 21f9f848faSopenharmony_ciSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 22f9f848faSopenharmony_ciWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 23f9f848faSopenharmony_ciIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 24f9f848faSopenharmony_ciARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 25f9f848faSopenharmony_ciTHIS SOFTWARE. 26f9f848faSopenharmony_ci 27f9f848faSopenharmony_ci****************************************************************/ 28f9f848faSopenharmony_ci 29f9f848faSopenharmony_ci/* Please send bug reports to David M. Gay (dmg at acm dot org, 30f9f848faSopenharmony_ci * with " at " changed at "@" and " dot " changed to "."). */ 31f9f848faSopenharmony_ci 32f9f848faSopenharmony_ci/* $FreeBSD$ */ 33f9f848faSopenharmony_ci 34f9f848faSopenharmony_ci#include "gdtoaimp.h" 35f9f848faSopenharmony_ci#ifndef NO_FENV_H 36f9f848faSopenharmony_ci#include <fenv.h> 37f9f848faSopenharmony_ci#endif 38f9f848faSopenharmony_ci 39f9f848faSopenharmony_ci#ifdef USE_LOCALE 40f9f848faSopenharmony_ci#include "locale.h" 41f9f848faSopenharmony_ci#endif 42f9f848faSopenharmony_ci 43f9f848faSopenharmony_ci#ifdef IEEE_Arith 44f9f848faSopenharmony_ci#ifndef NO_IEEE_Scale 45f9f848faSopenharmony_ci#define Avoid_Underflow 46f9f848faSopenharmony_ci#undef tinytens 47f9f848faSopenharmony_ci/* The factor of 2^106 in tinytens[4] helps us avoid setting the underflow */ 48f9f848faSopenharmony_ci/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ 49f9f848faSopenharmony_cistatic CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 50f9f848faSopenharmony_ci 9007199254740992.*9007199254740992.e-256 51f9f848faSopenharmony_ci }; 52f9f848faSopenharmony_ci#endif 53f9f848faSopenharmony_ci#endif 54f9f848faSopenharmony_ci 55f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS 56f9f848faSopenharmony_ci#undef Check_FLT_ROUNDS 57f9f848faSopenharmony_ci#define Check_FLT_ROUNDS 58f9f848faSopenharmony_ci#else 59f9f848faSopenharmony_ci#define Rounding Flt_Rounds 60f9f848faSopenharmony_ci#endif 61f9f848faSopenharmony_ci 62f9f848faSopenharmony_ci#ifdef Avoid_Underflow /*{*/ 63f9f848faSopenharmony_ci static double 64f9f848faSopenharmony_cisulp 65f9f848faSopenharmony_ci#ifdef KR_headers 66f9f848faSopenharmony_ci (x, scale) U *x; int scale; 67f9f848faSopenharmony_ci#else 68f9f848faSopenharmony_ci (U *x, int scale) 69f9f848faSopenharmony_ci#endif 70f9f848faSopenharmony_ci{ 71f9f848faSopenharmony_ci U u; 72f9f848faSopenharmony_ci double rv; 73f9f848faSopenharmony_ci int i; 74f9f848faSopenharmony_ci 75f9f848faSopenharmony_ci rv = ulp(x); 76f9f848faSopenharmony_ci if (!scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0) 77f9f848faSopenharmony_ci return rv; /* Is there an example where i <= 0 ? */ 78f9f848faSopenharmony_ci word0(&u) = Exp_1 + (i << Exp_shift); 79f9f848faSopenharmony_ci word1(&u) = 0; 80f9f848faSopenharmony_ci return rv * u.d; 81f9f848faSopenharmony_ci } 82f9f848faSopenharmony_ci#endif /*}*/ 83f9f848faSopenharmony_ci 84f9f848faSopenharmony_cistatic double 85f9f848faSopenharmony_cistrtod_l 86f9f848faSopenharmony_ci#ifdef KR_headers 87f9f848faSopenharmony_ci (s00, se, loc) CONST char *s00; char **se; locale_t loc 88f9f848faSopenharmony_ci#else 89f9f848faSopenharmony_ci (CONST char *s00, char **se, locale_t loc) 90f9f848faSopenharmony_ci#endif 91f9f848faSopenharmony_ci{ 92f9f848faSopenharmony_ci#ifdef Avoid_Underflow 93f9f848faSopenharmony_ci int scale; 94f9f848faSopenharmony_ci#endif 95f9f848faSopenharmony_ci int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, 96f9f848faSopenharmony_ci e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; 97f9f848faSopenharmony_ci CONST char *s, *s0, *s1; 98f9f848faSopenharmony_ci double aadj; 99f9f848faSopenharmony_ci Long L; 100f9f848faSopenharmony_ci U adj, aadj1, rv, rv0; 101f9f848faSopenharmony_ci ULong y, z; 102f9f848faSopenharmony_ci Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; 103f9f848faSopenharmony_ci#ifdef Avoid_Underflow 104f9f848faSopenharmony_ci ULong Lsb, Lsb1; 105f9f848faSopenharmony_ci#endif 106f9f848faSopenharmony_ci#ifdef SET_INEXACT 107f9f848faSopenharmony_ci int inexact, oldinexact; 108f9f848faSopenharmony_ci#endif 109f9f848faSopenharmony_ci#ifdef USE_LOCALE /*{{*/ 110f9f848faSopenharmony_ci#ifdef NO_LOCALE_CACHE 111f9f848faSopenharmony_ci char *decimalpoint = localeconv_l(loc)->decimal_point; 112f9f848faSopenharmony_ci int dplen = strlen(decimalpoint); 113f9f848faSopenharmony_ci#else 114f9f848faSopenharmony_ci char *decimalpoint; 115f9f848faSopenharmony_ci static char *decimalpoint_cache; 116f9f848faSopenharmony_ci static int dplen; 117f9f848faSopenharmony_ci if (!(s0 = decimalpoint_cache)) { 118f9f848faSopenharmony_ci s0 = localeconv_l(loc)->decimal_point; 119f9f848faSopenharmony_ci if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) { 120f9f848faSopenharmony_ci strcpy(decimalpoint_cache, s0); 121f9f848faSopenharmony_ci s0 = decimalpoint_cache; 122f9f848faSopenharmony_ci } 123f9f848faSopenharmony_ci dplen = strlen(s0); 124f9f848faSopenharmony_ci } 125f9f848faSopenharmony_ci decimalpoint = (char*)s0; 126f9f848faSopenharmony_ci#endif /*NO_LOCALE_CACHE*/ 127f9f848faSopenharmony_ci#else /*USE_LOCALE}{*/ 128f9f848faSopenharmony_ci#define dplen 1 129f9f848faSopenharmony_ci#endif /*USE_LOCALE}}*/ 130f9f848faSopenharmony_ci 131f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS /*{*/ 132f9f848faSopenharmony_ci int Rounding; 133f9f848faSopenharmony_ci#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ 134f9f848faSopenharmony_ci Rounding = Flt_Rounds; 135f9f848faSopenharmony_ci#else /*}{*/ 136f9f848faSopenharmony_ci Rounding = 1; 137f9f848faSopenharmony_ci switch(fegetround()) { 138f9f848faSopenharmony_ci case FE_TOWARDZERO: Rounding = 0; break; 139f9f848faSopenharmony_ci case FE_UPWARD: Rounding = 2; break; 140f9f848faSopenharmony_ci case FE_DOWNWARD: Rounding = 3; 141f9f848faSopenharmony_ci } 142f9f848faSopenharmony_ci#endif /*}}*/ 143f9f848faSopenharmony_ci#endif /*}*/ 144f9f848faSopenharmony_ci 145f9f848faSopenharmony_ci sign = nz0 = nz = decpt = 0; 146f9f848faSopenharmony_ci dval(&rv) = 0.; 147f9f848faSopenharmony_ci for(s = s00;;s++) switch(*s) { 148f9f848faSopenharmony_ci case '-': 149f9f848faSopenharmony_ci sign = 1; 150f9f848faSopenharmony_ci /* no break */ 151f9f848faSopenharmony_ci case '+': 152f9f848faSopenharmony_ci if (*++s) 153f9f848faSopenharmony_ci goto break2; 154f9f848faSopenharmony_ci /* no break */ 155f9f848faSopenharmony_ci case 0: 156f9f848faSopenharmony_ci goto ret0; 157f9f848faSopenharmony_ci case '\t': 158f9f848faSopenharmony_ci case '\n': 159f9f848faSopenharmony_ci case '\v': 160f9f848faSopenharmony_ci case '\f': 161f9f848faSopenharmony_ci case '\r': 162f9f848faSopenharmony_ci case ' ': 163f9f848faSopenharmony_ci continue; 164f9f848faSopenharmony_ci default: 165f9f848faSopenharmony_ci goto break2; 166f9f848faSopenharmony_ci } 167f9f848faSopenharmony_ci break2: 168f9f848faSopenharmony_ci if (*s == '0') { 169f9f848faSopenharmony_ci#ifndef NO_HEX_FP /*{*/ 170f9f848faSopenharmony_ci { 171f9f848faSopenharmony_ci static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; 172f9f848faSopenharmony_ci Long exp; 173f9f848faSopenharmony_ci ULong bits[2]; 174f9f848faSopenharmony_ci switch(s[1]) { 175f9f848faSopenharmony_ci case 'x': 176f9f848faSopenharmony_ci case 'X': 177f9f848faSopenharmony_ci { 178f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS 179f9f848faSopenharmony_ci FPI fpi1 = fpi; 180f9f848faSopenharmony_ci fpi1.rounding = Rounding; 181f9f848faSopenharmony_ci#else 182f9f848faSopenharmony_ci#define fpi1 fpi 183f9f848faSopenharmony_ci#endif 184f9f848faSopenharmony_ci switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { 185f9f848faSopenharmony_ci case STRTOG_NoNumber: 186f9f848faSopenharmony_ci s = s00; 187f9f848faSopenharmony_ci sign = 0; 188f9f848faSopenharmony_ci case STRTOG_Zero: 189f9f848faSopenharmony_ci break; 190f9f848faSopenharmony_ci default: 191f9f848faSopenharmony_ci if (bb) { 192f9f848faSopenharmony_ci copybits(bits, fpi.nbits, bb); 193f9f848faSopenharmony_ci Bfree(bb); 194f9f848faSopenharmony_ci } 195f9f848faSopenharmony_ci ULtod(((U*)&rv)->L, bits, exp, i); 196f9f848faSopenharmony_ci }} 197f9f848faSopenharmony_ci goto ret; 198f9f848faSopenharmony_ci } 199f9f848faSopenharmony_ci } 200f9f848faSopenharmony_ci#endif /*}*/ 201f9f848faSopenharmony_ci nz0 = 1; 202f9f848faSopenharmony_ci while(*++s == '0') ; 203f9f848faSopenharmony_ci if (!*s) 204f9f848faSopenharmony_ci goto ret; 205f9f848faSopenharmony_ci } 206f9f848faSopenharmony_ci s0 = s; 207f9f848faSopenharmony_ci y = z = 0; 208f9f848faSopenharmony_ci for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) 209f9f848faSopenharmony_ci if (nd < 9) 210f9f848faSopenharmony_ci y = 10*y + c - '0'; 211f9f848faSopenharmony_ci else if (nd < 16) 212f9f848faSopenharmony_ci z = 10*z + c - '0'; 213f9f848faSopenharmony_ci nd0 = nd; 214f9f848faSopenharmony_ci#ifdef USE_LOCALE 215f9f848faSopenharmony_ci if (c == *decimalpoint) { 216f9f848faSopenharmony_ci for(i = 1; decimalpoint[i]; ++i) 217f9f848faSopenharmony_ci if (s[i] != decimalpoint[i]) 218f9f848faSopenharmony_ci goto dig_done; 219f9f848faSopenharmony_ci s += i; 220f9f848faSopenharmony_ci c = *s; 221f9f848faSopenharmony_ci#else 222f9f848faSopenharmony_ci if (c == '.') { 223f9f848faSopenharmony_ci c = *++s; 224f9f848faSopenharmony_ci#endif 225f9f848faSopenharmony_ci decpt = 1; 226f9f848faSopenharmony_ci if (!nd) { 227f9f848faSopenharmony_ci for(; c == '0'; c = *++s) 228f9f848faSopenharmony_ci nz++; 229f9f848faSopenharmony_ci if (c > '0' && c <= '9') { 230f9f848faSopenharmony_ci s0 = s; 231f9f848faSopenharmony_ci nf += nz; 232f9f848faSopenharmony_ci nz = 0; 233f9f848faSopenharmony_ci goto have_dig; 234f9f848faSopenharmony_ci } 235f9f848faSopenharmony_ci goto dig_done; 236f9f848faSopenharmony_ci } 237f9f848faSopenharmony_ci for(; c >= '0' && c <= '9'; c = *++s) { 238f9f848faSopenharmony_ci have_dig: 239f9f848faSopenharmony_ci nz++; 240f9f848faSopenharmony_ci if (c -= '0') { 241f9f848faSopenharmony_ci nf += nz; 242f9f848faSopenharmony_ci for(i = 1; i < nz; i++) 243f9f848faSopenharmony_ci if (nd++ < 9) 244f9f848faSopenharmony_ci y *= 10; 245f9f848faSopenharmony_ci else if (nd <= DBL_DIG + 1) 246f9f848faSopenharmony_ci z *= 10; 247f9f848faSopenharmony_ci if (nd++ < 9) 248f9f848faSopenharmony_ci y = 10*y + c; 249f9f848faSopenharmony_ci else if (nd <= DBL_DIG + 1) 250f9f848faSopenharmony_ci z = 10*z + c; 251f9f848faSopenharmony_ci nz = 0; 252f9f848faSopenharmony_ci } 253f9f848faSopenharmony_ci } 254f9f848faSopenharmony_ci }/*}*/ 255f9f848faSopenharmony_ci dig_done: 256f9f848faSopenharmony_ci e = 0; 257f9f848faSopenharmony_ci if (c == 'e' || c == 'E') { 258f9f848faSopenharmony_ci if (!nd && !nz && !nz0) { 259f9f848faSopenharmony_ci goto ret0; 260f9f848faSopenharmony_ci } 261f9f848faSopenharmony_ci s00 = s; 262f9f848faSopenharmony_ci esign = 0; 263f9f848faSopenharmony_ci switch(c = *++s) { 264f9f848faSopenharmony_ci case '-': 265f9f848faSopenharmony_ci esign = 1; 266f9f848faSopenharmony_ci case '+': 267f9f848faSopenharmony_ci c = *++s; 268f9f848faSopenharmony_ci } 269f9f848faSopenharmony_ci if (c >= '0' && c <= '9') { 270f9f848faSopenharmony_ci while(c == '0') 271f9f848faSopenharmony_ci c = *++s; 272f9f848faSopenharmony_ci if (c > '0' && c <= '9') { 273f9f848faSopenharmony_ci L = c - '0'; 274f9f848faSopenharmony_ci s1 = s; 275f9f848faSopenharmony_ci while((c = *++s) >= '0' && c <= '9') 276f9f848faSopenharmony_ci L = 10*L + c - '0'; 277f9f848faSopenharmony_ci if (s - s1 > 8 || L > 19999) 278f9f848faSopenharmony_ci /* Avoid confusion from exponents 279f9f848faSopenharmony_ci * so large that e might overflow. 280f9f848faSopenharmony_ci */ 281f9f848faSopenharmony_ci e = 19999; /* safe for 16 bit ints */ 282f9f848faSopenharmony_ci else 283f9f848faSopenharmony_ci e = (int)L; 284f9f848faSopenharmony_ci if (esign) 285f9f848faSopenharmony_ci e = -e; 286f9f848faSopenharmony_ci } 287f9f848faSopenharmony_ci else 288f9f848faSopenharmony_ci e = 0; 289f9f848faSopenharmony_ci } 290f9f848faSopenharmony_ci else 291f9f848faSopenharmony_ci s = s00; 292f9f848faSopenharmony_ci } 293f9f848faSopenharmony_ci if (!nd) { 294f9f848faSopenharmony_ci if (!nz && !nz0) { 295f9f848faSopenharmony_ci#ifdef INFNAN_CHECK 296f9f848faSopenharmony_ci /* Check for Nan and Infinity */ 297f9f848faSopenharmony_ci ULong bits[2]; 298f9f848faSopenharmony_ci static FPI fpinan = /* only 52 explicit bits */ 299f9f848faSopenharmony_ci { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; 300f9f848faSopenharmony_ci if (!decpt) 301f9f848faSopenharmony_ci switch(c) { 302f9f848faSopenharmony_ci case 'i': 303f9f848faSopenharmony_ci case 'I': 304f9f848faSopenharmony_ci if (match(&s,"nf")) { 305f9f848faSopenharmony_ci --s; 306f9f848faSopenharmony_ci if (!match(&s,"inity")) 307f9f848faSopenharmony_ci ++s; 308f9f848faSopenharmony_ci word0(&rv) = 0x7ff00000; 309f9f848faSopenharmony_ci word1(&rv) = 0; 310f9f848faSopenharmony_ci goto ret; 311f9f848faSopenharmony_ci } 312f9f848faSopenharmony_ci break; 313f9f848faSopenharmony_ci case 'n': 314f9f848faSopenharmony_ci case 'N': 315f9f848faSopenharmony_ci if (match(&s, "an")) { 316f9f848faSopenharmony_ci#ifndef No_Hex_NaN 317f9f848faSopenharmony_ci if (*s == '(' /*)*/ 318f9f848faSopenharmony_ci && hexnan(&s, &fpinan, bits) 319f9f848faSopenharmony_ci == STRTOG_NaNbits) { 320f9f848faSopenharmony_ci word0(&rv) = 0x7ff80000 | bits[1]; 321f9f848faSopenharmony_ci word1(&rv) = bits[0]; 322f9f848faSopenharmony_ci } 323f9f848faSopenharmony_ci else { 324f9f848faSopenharmony_ci#endif 325f9f848faSopenharmony_ci word0(&rv) = NAN_WORD0; 326f9f848faSopenharmony_ci word1(&rv) = NAN_WORD1; 327f9f848faSopenharmony_ci#ifndef No_Hex_NaN 328f9f848faSopenharmony_ci } 329f9f848faSopenharmony_ci#endif 330f9f848faSopenharmony_ci goto ret; 331f9f848faSopenharmony_ci } 332f9f848faSopenharmony_ci } 333f9f848faSopenharmony_ci#endif /* INFNAN_CHECK */ 334f9f848faSopenharmony_ci ret0: 335f9f848faSopenharmony_ci s = s00; 336f9f848faSopenharmony_ci sign = 0; 337f9f848faSopenharmony_ci } 338f9f848faSopenharmony_ci goto ret; 339f9f848faSopenharmony_ci } 340f9f848faSopenharmony_ci e1 = e -= nf; 341f9f848faSopenharmony_ci 342f9f848faSopenharmony_ci /* Now we have nd0 digits, starting at s0, followed by a 343f9f848faSopenharmony_ci * decimal point, followed by nd-nd0 digits. The number we're 344f9f848faSopenharmony_ci * after is the integer represented by those digits times 345f9f848faSopenharmony_ci * 10**e */ 346f9f848faSopenharmony_ci 347f9f848faSopenharmony_ci if (!nd0) 348f9f848faSopenharmony_ci nd0 = nd; 349f9f848faSopenharmony_ci k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; 350f9f848faSopenharmony_ci dval(&rv) = y; 351f9f848faSopenharmony_ci if (k > 9) { 352f9f848faSopenharmony_ci#ifdef SET_INEXACT 353f9f848faSopenharmony_ci if (k > DBL_DIG) 354f9f848faSopenharmony_ci oldinexact = get_inexact(); 355f9f848faSopenharmony_ci#endif 356f9f848faSopenharmony_ci dval(&rv) = tens[k - 9] * dval(&rv) + z; 357f9f848faSopenharmony_ci } 358f9f848faSopenharmony_ci bd0 = 0; 359f9f848faSopenharmony_ci if (nd <= DBL_DIG 360f9f848faSopenharmony_ci#ifndef RND_PRODQUOT 361f9f848faSopenharmony_ci#ifndef Honor_FLT_ROUNDS 362f9f848faSopenharmony_ci && Flt_Rounds == 1 363f9f848faSopenharmony_ci#endif 364f9f848faSopenharmony_ci#endif 365f9f848faSopenharmony_ci ) { 366f9f848faSopenharmony_ci if (!e) 367f9f848faSopenharmony_ci goto ret; 368f9f848faSopenharmony_ci#ifndef ROUND_BIASED_without_Round_Up 369f9f848faSopenharmony_ci if (e > 0) { 370f9f848faSopenharmony_ci if (e <= Ten_pmax) { 371f9f848faSopenharmony_ci#ifdef VAX 372f9f848faSopenharmony_ci goto vax_ovfl_check; 373f9f848faSopenharmony_ci#else 374f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS 375f9f848faSopenharmony_ci /* round correctly FLT_ROUNDS = 2 or 3 */ 376f9f848faSopenharmony_ci if (sign) { 377f9f848faSopenharmony_ci rv.d = -rv.d; 378f9f848faSopenharmony_ci sign = 0; 379f9f848faSopenharmony_ci } 380f9f848faSopenharmony_ci#endif 381f9f848faSopenharmony_ci /* rv = */ rounded_product(dval(&rv), tens[e]); 382f9f848faSopenharmony_ci goto ret; 383f9f848faSopenharmony_ci#endif 384f9f848faSopenharmony_ci } 385f9f848faSopenharmony_ci i = DBL_DIG - nd; 386f9f848faSopenharmony_ci if (e <= Ten_pmax + i) { 387f9f848faSopenharmony_ci /* A fancier test would sometimes let us do 388f9f848faSopenharmony_ci * this for larger i values. 389f9f848faSopenharmony_ci */ 390f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS 391f9f848faSopenharmony_ci /* round correctly FLT_ROUNDS = 2 or 3 */ 392f9f848faSopenharmony_ci if (sign) { 393f9f848faSopenharmony_ci rv.d = -rv.d; 394f9f848faSopenharmony_ci sign = 0; 395f9f848faSopenharmony_ci } 396f9f848faSopenharmony_ci#endif 397f9f848faSopenharmony_ci e -= i; 398f9f848faSopenharmony_ci dval(&rv) *= tens[i]; 399f9f848faSopenharmony_ci#ifdef VAX 400f9f848faSopenharmony_ci /* VAX exponent range is so narrow we must 401f9f848faSopenharmony_ci * worry about overflow here... 402f9f848faSopenharmony_ci */ 403f9f848faSopenharmony_ci vax_ovfl_check: 404f9f848faSopenharmony_ci word0(&rv) -= P*Exp_msk1; 405f9f848faSopenharmony_ci /* rv = */ rounded_product(dval(&rv), tens[e]); 406f9f848faSopenharmony_ci if ((word0(&rv) & Exp_mask) 407f9f848faSopenharmony_ci > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) 408f9f848faSopenharmony_ci goto ovfl; 409f9f848faSopenharmony_ci word0(&rv) += P*Exp_msk1; 410f9f848faSopenharmony_ci#else 411f9f848faSopenharmony_ci /* rv = */ rounded_product(dval(&rv), tens[e]); 412f9f848faSopenharmony_ci#endif 413f9f848faSopenharmony_ci goto ret; 414f9f848faSopenharmony_ci } 415f9f848faSopenharmony_ci } 416f9f848faSopenharmony_ci#ifndef Inaccurate_Divide 417f9f848faSopenharmony_ci else if (e >= -Ten_pmax) { 418f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS 419f9f848faSopenharmony_ci /* round correctly FLT_ROUNDS = 2 or 3 */ 420f9f848faSopenharmony_ci if (sign) { 421f9f848faSopenharmony_ci rv.d = -rv.d; 422f9f848faSopenharmony_ci sign = 0; 423f9f848faSopenharmony_ci } 424f9f848faSopenharmony_ci#endif 425f9f848faSopenharmony_ci /* rv = */ rounded_quotient(dval(&rv), tens[-e]); 426f9f848faSopenharmony_ci goto ret; 427f9f848faSopenharmony_ci } 428f9f848faSopenharmony_ci#endif 429f9f848faSopenharmony_ci#endif /* ROUND_BIASED_without_Round_Up */ 430f9f848faSopenharmony_ci } 431f9f848faSopenharmony_ci e1 += nd - k; 432f9f848faSopenharmony_ci 433f9f848faSopenharmony_ci#ifdef IEEE_Arith 434f9f848faSopenharmony_ci#ifdef SET_INEXACT 435f9f848faSopenharmony_ci inexact = 1; 436f9f848faSopenharmony_ci if (k <= DBL_DIG) 437f9f848faSopenharmony_ci oldinexact = get_inexact(); 438f9f848faSopenharmony_ci#endif 439f9f848faSopenharmony_ci#ifdef Avoid_Underflow 440f9f848faSopenharmony_ci scale = 0; 441f9f848faSopenharmony_ci#endif 442f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS 443f9f848faSopenharmony_ci if (Rounding >= 2) { 444f9f848faSopenharmony_ci if (sign) 445f9f848faSopenharmony_ci Rounding = Rounding == 2 ? 0 : 2; 446f9f848faSopenharmony_ci else 447f9f848faSopenharmony_ci if (Rounding != 2) 448f9f848faSopenharmony_ci Rounding = 0; 449f9f848faSopenharmony_ci } 450f9f848faSopenharmony_ci#endif 451f9f848faSopenharmony_ci#endif /*IEEE_Arith*/ 452f9f848faSopenharmony_ci 453f9f848faSopenharmony_ci /* Get starting approximation = rv * 10**e1 */ 454f9f848faSopenharmony_ci 455f9f848faSopenharmony_ci if (e1 > 0) { 456f9f848faSopenharmony_ci if ( (i = e1 & 15) !=0) 457f9f848faSopenharmony_ci dval(&rv) *= tens[i]; 458f9f848faSopenharmony_ci if (e1 &= ~15) { 459f9f848faSopenharmony_ci if (e1 > DBL_MAX_10_EXP) { 460f9f848faSopenharmony_ci ovfl: 461f9f848faSopenharmony_ci /* Can't trust HUGE_VAL */ 462f9f848faSopenharmony_ci#ifdef IEEE_Arith 463f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS 464f9f848faSopenharmony_ci switch(Rounding) { 465f9f848faSopenharmony_ci case 0: /* toward 0 */ 466f9f848faSopenharmony_ci case 3: /* toward -infinity */ 467f9f848faSopenharmony_ci word0(&rv) = Big0; 468f9f848faSopenharmony_ci word1(&rv) = Big1; 469f9f848faSopenharmony_ci break; 470f9f848faSopenharmony_ci default: 471f9f848faSopenharmony_ci word0(&rv) = Exp_mask; 472f9f848faSopenharmony_ci word1(&rv) = 0; 473f9f848faSopenharmony_ci } 474f9f848faSopenharmony_ci#else /*Honor_FLT_ROUNDS*/ 475f9f848faSopenharmony_ci word0(&rv) = Exp_mask; 476f9f848faSopenharmony_ci word1(&rv) = 0; 477f9f848faSopenharmony_ci#endif /*Honor_FLT_ROUNDS*/ 478f9f848faSopenharmony_ci#ifdef SET_INEXACT 479f9f848faSopenharmony_ci /* set overflow bit */ 480f9f848faSopenharmony_ci dval(&rv0) = 1e300; 481f9f848faSopenharmony_ci dval(&rv0) *= dval(&rv0); 482f9f848faSopenharmony_ci#endif 483f9f848faSopenharmony_ci#else /*IEEE_Arith*/ 484f9f848faSopenharmony_ci word0(&rv) = Big0; 485f9f848faSopenharmony_ci word1(&rv) = Big1; 486f9f848faSopenharmony_ci#endif /*IEEE_Arith*/ 487f9f848faSopenharmony_ci range_err: 488f9f848faSopenharmony_ci if (bd0) { 489f9f848faSopenharmony_ci Bfree(bb); 490f9f848faSopenharmony_ci Bfree(bd); 491f9f848faSopenharmony_ci Bfree(bs); 492f9f848faSopenharmony_ci Bfree(bd0); 493f9f848faSopenharmony_ci Bfree(delta); 494f9f848faSopenharmony_ci } 495f9f848faSopenharmony_ci#ifndef NO_ERRNO 496f9f848faSopenharmony_ci errno = ERANGE; 497f9f848faSopenharmony_ci#endif 498f9f848faSopenharmony_ci goto ret; 499f9f848faSopenharmony_ci } 500f9f848faSopenharmony_ci e1 >>= 4; 501f9f848faSopenharmony_ci for(j = 0; e1 > 1; j++, e1 >>= 1) 502f9f848faSopenharmony_ci if (e1 & 1) 503f9f848faSopenharmony_ci dval(&rv) *= bigtens[j]; 504f9f848faSopenharmony_ci /* The last multiplication could overflow. */ 505f9f848faSopenharmony_ci word0(&rv) -= P*Exp_msk1; 506f9f848faSopenharmony_ci dval(&rv) *= bigtens[j]; 507f9f848faSopenharmony_ci if ((z = word0(&rv) & Exp_mask) 508f9f848faSopenharmony_ci > Exp_msk1*(DBL_MAX_EXP+Bias-P)) 509f9f848faSopenharmony_ci goto ovfl; 510f9f848faSopenharmony_ci if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { 511f9f848faSopenharmony_ci /* set to largest number */ 512f9f848faSopenharmony_ci /* (Can't trust DBL_MAX) */ 513f9f848faSopenharmony_ci word0(&rv) = Big0; 514f9f848faSopenharmony_ci word1(&rv) = Big1; 515f9f848faSopenharmony_ci } 516f9f848faSopenharmony_ci else 517f9f848faSopenharmony_ci word0(&rv) += P*Exp_msk1; 518f9f848faSopenharmony_ci } 519f9f848faSopenharmony_ci } 520f9f848faSopenharmony_ci else if (e1 < 0) { 521f9f848faSopenharmony_ci e1 = -e1; 522f9f848faSopenharmony_ci if ( (i = e1 & 15) !=0) 523f9f848faSopenharmony_ci dval(&rv) /= tens[i]; 524f9f848faSopenharmony_ci if (e1 >>= 4) { 525f9f848faSopenharmony_ci if (e1 >= 1 << n_bigtens) 526f9f848faSopenharmony_ci goto undfl; 527f9f848faSopenharmony_ci#ifdef Avoid_Underflow 528f9f848faSopenharmony_ci if (e1 & Scale_Bit) 529f9f848faSopenharmony_ci scale = 2*P; 530f9f848faSopenharmony_ci for(j = 0; e1 > 0; j++, e1 >>= 1) 531f9f848faSopenharmony_ci if (e1 & 1) 532f9f848faSopenharmony_ci dval(&rv) *= tinytens[j]; 533f9f848faSopenharmony_ci if (scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) 534f9f848faSopenharmony_ci >> Exp_shift)) > 0) { 535f9f848faSopenharmony_ci /* scaled rv is denormal; zap j low bits */ 536f9f848faSopenharmony_ci if (j >= 32) { 537f9f848faSopenharmony_ci word1(&rv) = 0; 538f9f848faSopenharmony_ci if (j >= 53) 539f9f848faSopenharmony_ci word0(&rv) = (P+2)*Exp_msk1; 540f9f848faSopenharmony_ci else 541f9f848faSopenharmony_ci word0(&rv) &= 0xffffffff << (j-32); 542f9f848faSopenharmony_ci } 543f9f848faSopenharmony_ci else 544f9f848faSopenharmony_ci word1(&rv) &= 0xffffffff << j; 545f9f848faSopenharmony_ci } 546f9f848faSopenharmony_ci#else 547f9f848faSopenharmony_ci for(j = 0; e1 > 1; j++, e1 >>= 1) 548f9f848faSopenharmony_ci if (e1 & 1) 549f9f848faSopenharmony_ci dval(&rv) *= tinytens[j]; 550f9f848faSopenharmony_ci /* The last multiplication could underflow. */ 551f9f848faSopenharmony_ci dval(&rv0) = dval(&rv); 552f9f848faSopenharmony_ci dval(&rv) *= tinytens[j]; 553f9f848faSopenharmony_ci if (!dval(&rv)) { 554f9f848faSopenharmony_ci dval(&rv) = 2.*dval(&rv0); 555f9f848faSopenharmony_ci dval(&rv) *= tinytens[j]; 556f9f848faSopenharmony_ci#endif 557f9f848faSopenharmony_ci if (!dval(&rv)) { 558f9f848faSopenharmony_ci undfl: 559f9f848faSopenharmony_ci dval(&rv) = 0.; 560f9f848faSopenharmony_ci goto range_err; 561f9f848faSopenharmony_ci } 562f9f848faSopenharmony_ci#ifndef Avoid_Underflow 563f9f848faSopenharmony_ci word0(&rv) = Tiny0; 564f9f848faSopenharmony_ci word1(&rv) = Tiny1; 565f9f848faSopenharmony_ci /* The refinement below will clean 566f9f848faSopenharmony_ci * this approximation up. 567f9f848faSopenharmony_ci */ 568f9f848faSopenharmony_ci } 569f9f848faSopenharmony_ci#endif 570f9f848faSopenharmony_ci } 571f9f848faSopenharmony_ci } 572f9f848faSopenharmony_ci 573f9f848faSopenharmony_ci /* Now the hard part -- adjusting rv to the correct value.*/ 574f9f848faSopenharmony_ci 575f9f848faSopenharmony_ci /* Put digits into bd: true value = bd * 10^e */ 576f9f848faSopenharmony_ci 577f9f848faSopenharmony_ci bd0 = s2b(s0, nd0, nd, y, dplen); 578f9f848faSopenharmony_ci 579f9f848faSopenharmony_ci for(;;) { 580f9f848faSopenharmony_ci bd = Balloc(bd0->k); 581f9f848faSopenharmony_ci Bcopy(bd, bd0); 582f9f848faSopenharmony_ci bb = d2b(dval(&rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ 583f9f848faSopenharmony_ci bs = i2b(1); 584f9f848faSopenharmony_ci 585f9f848faSopenharmony_ci if (e >= 0) { 586f9f848faSopenharmony_ci bb2 = bb5 = 0; 587f9f848faSopenharmony_ci bd2 = bd5 = e; 588f9f848faSopenharmony_ci } 589f9f848faSopenharmony_ci else { 590f9f848faSopenharmony_ci bb2 = bb5 = -e; 591f9f848faSopenharmony_ci bd2 = bd5 = 0; 592f9f848faSopenharmony_ci } 593f9f848faSopenharmony_ci if (bbe >= 0) 594f9f848faSopenharmony_ci bb2 += bbe; 595f9f848faSopenharmony_ci else 596f9f848faSopenharmony_ci bd2 -= bbe; 597f9f848faSopenharmony_ci bs2 = bb2; 598f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS 599f9f848faSopenharmony_ci if (Rounding != 1) 600f9f848faSopenharmony_ci bs2++; 601f9f848faSopenharmony_ci#endif 602f9f848faSopenharmony_ci#ifdef Avoid_Underflow 603f9f848faSopenharmony_ci Lsb = LSB; 604f9f848faSopenharmony_ci Lsb1 = 0; 605f9f848faSopenharmony_ci j = bbe - scale; 606f9f848faSopenharmony_ci i = j + bbbits - 1; /* logb(rv) */ 607f9f848faSopenharmony_ci j = P + 1 - bbbits; 608f9f848faSopenharmony_ci if (i < Emin) { /* denormal */ 609f9f848faSopenharmony_ci i = Emin - i; 610f9f848faSopenharmony_ci j -= i; 611f9f848faSopenharmony_ci if (i < 32) 612f9f848faSopenharmony_ci Lsb <<= i; 613f9f848faSopenharmony_ci else 614f9f848faSopenharmony_ci Lsb1 = Lsb << (i-32); 615f9f848faSopenharmony_ci } 616f9f848faSopenharmony_ci#else /*Avoid_Underflow*/ 617f9f848faSopenharmony_ci#ifdef Sudden_Underflow 618f9f848faSopenharmony_ci#ifdef IBM 619f9f848faSopenharmony_ci j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); 620f9f848faSopenharmony_ci#else 621f9f848faSopenharmony_ci j = P + 1 - bbbits; 622f9f848faSopenharmony_ci#endif 623f9f848faSopenharmony_ci#else /*Sudden_Underflow*/ 624f9f848faSopenharmony_ci j = bbe; 625f9f848faSopenharmony_ci i = j + bbbits - 1; /* logb(&rv) */ 626f9f848faSopenharmony_ci if (i < Emin) /* denormal */ 627f9f848faSopenharmony_ci j += P - Emin; 628f9f848faSopenharmony_ci else 629f9f848faSopenharmony_ci j = P + 1 - bbbits; 630f9f848faSopenharmony_ci#endif /*Sudden_Underflow*/ 631f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/ 632f9f848faSopenharmony_ci bb2 += j; 633f9f848faSopenharmony_ci bd2 += j; 634f9f848faSopenharmony_ci#ifdef Avoid_Underflow 635f9f848faSopenharmony_ci bd2 += scale; 636f9f848faSopenharmony_ci#endif 637f9f848faSopenharmony_ci i = bb2 < bd2 ? bb2 : bd2; 638f9f848faSopenharmony_ci if (i > bs2) 639f9f848faSopenharmony_ci i = bs2; 640f9f848faSopenharmony_ci if (i > 0) { 641f9f848faSopenharmony_ci bb2 -= i; 642f9f848faSopenharmony_ci bd2 -= i; 643f9f848faSopenharmony_ci bs2 -= i; 644f9f848faSopenharmony_ci } 645f9f848faSopenharmony_ci if (bb5 > 0) { 646f9f848faSopenharmony_ci bs = pow5mult(bs, bb5); 647f9f848faSopenharmony_ci bb1 = mult(bs, bb); 648f9f848faSopenharmony_ci Bfree(bb); 649f9f848faSopenharmony_ci bb = bb1; 650f9f848faSopenharmony_ci } 651f9f848faSopenharmony_ci if (bb2 > 0) 652f9f848faSopenharmony_ci bb = lshift(bb, bb2); 653f9f848faSopenharmony_ci if (bd5 > 0) 654f9f848faSopenharmony_ci bd = pow5mult(bd, bd5); 655f9f848faSopenharmony_ci if (bd2 > 0) 656f9f848faSopenharmony_ci bd = lshift(bd, bd2); 657f9f848faSopenharmony_ci if (bs2 > 0) 658f9f848faSopenharmony_ci bs = lshift(bs, bs2); 659f9f848faSopenharmony_ci delta = diff(bb, bd); 660f9f848faSopenharmony_ci dsign = delta->sign; 661f9f848faSopenharmony_ci delta->sign = 0; 662f9f848faSopenharmony_ci i = cmp(delta, bs); 663f9f848faSopenharmony_ci#ifdef Honor_FLT_ROUNDS 664f9f848faSopenharmony_ci if (Rounding != 1) { 665f9f848faSopenharmony_ci if (i < 0) { 666f9f848faSopenharmony_ci /* Error is less than an ulp */ 667f9f848faSopenharmony_ci if (!delta->x[0] && delta->wds <= 1) { 668f9f848faSopenharmony_ci /* exact */ 669f9f848faSopenharmony_ci#ifdef SET_INEXACT 670f9f848faSopenharmony_ci inexact = 0; 671f9f848faSopenharmony_ci#endif 672f9f848faSopenharmony_ci break; 673f9f848faSopenharmony_ci } 674f9f848faSopenharmony_ci if (Rounding) { 675f9f848faSopenharmony_ci if (dsign) { 676f9f848faSopenharmony_ci dval(&adj) = 1.; 677f9f848faSopenharmony_ci goto apply_adj; 678f9f848faSopenharmony_ci } 679f9f848faSopenharmony_ci } 680f9f848faSopenharmony_ci else if (!dsign) { 681f9f848faSopenharmony_ci dval(&adj) = -1.; 682f9f848faSopenharmony_ci if (!word1(&rv) 683f9f848faSopenharmony_ci && !(word0(&rv) & Frac_mask)) { 684f9f848faSopenharmony_ci y = word0(&rv) & Exp_mask; 685f9f848faSopenharmony_ci#ifdef Avoid_Underflow 686f9f848faSopenharmony_ci if (!scale || y > 2*P*Exp_msk1) 687f9f848faSopenharmony_ci#else 688f9f848faSopenharmony_ci if (y) 689f9f848faSopenharmony_ci#endif 690f9f848faSopenharmony_ci { 691f9f848faSopenharmony_ci delta = lshift(delta,Log2P); 692f9f848faSopenharmony_ci if (cmp(delta, bs) <= 0) 693f9f848faSopenharmony_ci dval(&adj) = -0.5; 694f9f848faSopenharmony_ci } 695f9f848faSopenharmony_ci } 696f9f848faSopenharmony_ci apply_adj: 697f9f848faSopenharmony_ci#ifdef Avoid_Underflow 698f9f848faSopenharmony_ci if (scale && (y = word0(&rv) & Exp_mask) 699f9f848faSopenharmony_ci <= 2*P*Exp_msk1) 700f9f848faSopenharmony_ci word0(&adj) += (2*P+1)*Exp_msk1 - y; 701f9f848faSopenharmony_ci#else 702f9f848faSopenharmony_ci#ifdef Sudden_Underflow 703f9f848faSopenharmony_ci if ((word0(&rv) & Exp_mask) <= 704f9f848faSopenharmony_ci P*Exp_msk1) { 705f9f848faSopenharmony_ci word0(&rv) += P*Exp_msk1; 706f9f848faSopenharmony_ci dval(&rv) += adj*ulp(&rv); 707f9f848faSopenharmony_ci word0(&rv) -= P*Exp_msk1; 708f9f848faSopenharmony_ci } 709f9f848faSopenharmony_ci else 710f9f848faSopenharmony_ci#endif /*Sudden_Underflow*/ 711f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/ 712f9f848faSopenharmony_ci dval(&rv) += adj.d*ulp(&rv); 713f9f848faSopenharmony_ci } 714f9f848faSopenharmony_ci break; 715f9f848faSopenharmony_ci } 716f9f848faSopenharmony_ci dval(&adj) = ratio(delta, bs); 717f9f848faSopenharmony_ci if (adj.d < 1.) 718f9f848faSopenharmony_ci dval(&adj) = 1.; 719f9f848faSopenharmony_ci if (adj.d <= 0x7ffffffe) { 720f9f848faSopenharmony_ci /* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */ 721f9f848faSopenharmony_ci y = adj.d; 722f9f848faSopenharmony_ci if (y != adj.d) { 723f9f848faSopenharmony_ci if (!((Rounding>>1) ^ dsign)) 724f9f848faSopenharmony_ci y++; 725f9f848faSopenharmony_ci dval(&adj) = y; 726f9f848faSopenharmony_ci } 727f9f848faSopenharmony_ci } 728f9f848faSopenharmony_ci#ifdef Avoid_Underflow 729f9f848faSopenharmony_ci if (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) 730f9f848faSopenharmony_ci word0(&adj) += (2*P+1)*Exp_msk1 - y; 731f9f848faSopenharmony_ci#else 732f9f848faSopenharmony_ci#ifdef Sudden_Underflow 733f9f848faSopenharmony_ci if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { 734f9f848faSopenharmony_ci word0(&rv) += P*Exp_msk1; 735f9f848faSopenharmony_ci dval(&adj) *= ulp(&rv); 736f9f848faSopenharmony_ci if (dsign) 737f9f848faSopenharmony_ci dval(&rv) += adj; 738f9f848faSopenharmony_ci else 739f9f848faSopenharmony_ci dval(&rv) -= adj; 740f9f848faSopenharmony_ci word0(&rv) -= P*Exp_msk1; 741f9f848faSopenharmony_ci goto cont; 742f9f848faSopenharmony_ci } 743f9f848faSopenharmony_ci#endif /*Sudden_Underflow*/ 744f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/ 745f9f848faSopenharmony_ci dval(&adj) *= ulp(&rv); 746f9f848faSopenharmony_ci if (dsign) { 747f9f848faSopenharmony_ci if (word0(&rv) == Big0 && word1(&rv) == Big1) 748f9f848faSopenharmony_ci goto ovfl; 749f9f848faSopenharmony_ci dval(&rv) += adj.d; 750f9f848faSopenharmony_ci } 751f9f848faSopenharmony_ci else 752f9f848faSopenharmony_ci dval(&rv) -= adj.d; 753f9f848faSopenharmony_ci goto cont; 754f9f848faSopenharmony_ci } 755f9f848faSopenharmony_ci#endif /*Honor_FLT_ROUNDS*/ 756f9f848faSopenharmony_ci 757f9f848faSopenharmony_ci if (i < 0) { 758f9f848faSopenharmony_ci /* Error is less than half an ulp -- check for 759f9f848faSopenharmony_ci * special case of mantissa a power of two. 760f9f848faSopenharmony_ci */ 761f9f848faSopenharmony_ci if (dsign || word1(&rv) || word0(&rv) & Bndry_mask 762f9f848faSopenharmony_ci#ifdef IEEE_Arith 763f9f848faSopenharmony_ci#ifdef Avoid_Underflow 764f9f848faSopenharmony_ci || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 765f9f848faSopenharmony_ci#else 766f9f848faSopenharmony_ci || (word0(&rv) & Exp_mask) <= Exp_msk1 767f9f848faSopenharmony_ci#endif 768f9f848faSopenharmony_ci#endif 769f9f848faSopenharmony_ci ) { 770f9f848faSopenharmony_ci#ifdef SET_INEXACT 771f9f848faSopenharmony_ci if (!delta->x[0] && delta->wds <= 1) 772f9f848faSopenharmony_ci inexact = 0; 773f9f848faSopenharmony_ci#endif 774f9f848faSopenharmony_ci break; 775f9f848faSopenharmony_ci } 776f9f848faSopenharmony_ci if (!delta->x[0] && delta->wds <= 1) { 777f9f848faSopenharmony_ci /* exact result */ 778f9f848faSopenharmony_ci#ifdef SET_INEXACT 779f9f848faSopenharmony_ci inexact = 0; 780f9f848faSopenharmony_ci#endif 781f9f848faSopenharmony_ci break; 782f9f848faSopenharmony_ci } 783f9f848faSopenharmony_ci delta = lshift(delta,Log2P); 784f9f848faSopenharmony_ci if (cmp(delta, bs) > 0) 785f9f848faSopenharmony_ci goto drop_down; 786f9f848faSopenharmony_ci break; 787f9f848faSopenharmony_ci } 788f9f848faSopenharmony_ci if (i == 0) { 789f9f848faSopenharmony_ci /* exactly half-way between */ 790f9f848faSopenharmony_ci if (dsign) { 791f9f848faSopenharmony_ci if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 792f9f848faSopenharmony_ci && word1(&rv) == ( 793f9f848faSopenharmony_ci#ifdef Avoid_Underflow 794f9f848faSopenharmony_ci (scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) 795f9f848faSopenharmony_ci ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : 796f9f848faSopenharmony_ci#endif 797f9f848faSopenharmony_ci 0xffffffff)) { 798f9f848faSopenharmony_ci /*boundary case -- increment exponent*/ 799f9f848faSopenharmony_ci if (word0(&rv) == Big0 && word1(&rv) == Big1) 800f9f848faSopenharmony_ci goto ovfl; 801f9f848faSopenharmony_ci word0(&rv) = (word0(&rv) & Exp_mask) 802f9f848faSopenharmony_ci + Exp_msk1 803f9f848faSopenharmony_ci#ifdef IBM 804f9f848faSopenharmony_ci | Exp_msk1 >> 4 805f9f848faSopenharmony_ci#endif 806f9f848faSopenharmony_ci ; 807f9f848faSopenharmony_ci word1(&rv) = 0; 808f9f848faSopenharmony_ci#ifdef Avoid_Underflow 809f9f848faSopenharmony_ci dsign = 0; 810f9f848faSopenharmony_ci#endif 811f9f848faSopenharmony_ci break; 812f9f848faSopenharmony_ci } 813f9f848faSopenharmony_ci } 814f9f848faSopenharmony_ci else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { 815f9f848faSopenharmony_ci drop_down: 816f9f848faSopenharmony_ci /* boundary case -- decrement exponent */ 817f9f848faSopenharmony_ci#ifdef Sudden_Underflow /*{{*/ 818f9f848faSopenharmony_ci L = word0(&rv) & Exp_mask; 819f9f848faSopenharmony_ci#ifdef IBM 820f9f848faSopenharmony_ci if (L < Exp_msk1) 821f9f848faSopenharmony_ci#else 822f9f848faSopenharmony_ci#ifdef Avoid_Underflow 823f9f848faSopenharmony_ci if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) 824f9f848faSopenharmony_ci#else 825f9f848faSopenharmony_ci if (L <= Exp_msk1) 826f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/ 827f9f848faSopenharmony_ci#endif /*IBM*/ 828f9f848faSopenharmony_ci goto undfl; 829f9f848faSopenharmony_ci L -= Exp_msk1; 830f9f848faSopenharmony_ci#else /*Sudden_Underflow}{*/ 831f9f848faSopenharmony_ci#ifdef Avoid_Underflow 832f9f848faSopenharmony_ci if (scale) { 833f9f848faSopenharmony_ci L = word0(&rv) & Exp_mask; 834f9f848faSopenharmony_ci if (L <= (2*P+1)*Exp_msk1) { 835f9f848faSopenharmony_ci if (L > (P+2)*Exp_msk1) 836f9f848faSopenharmony_ci /* round even ==> */ 837f9f848faSopenharmony_ci /* accept rv */ 838f9f848faSopenharmony_ci break; 839f9f848faSopenharmony_ci /* rv = smallest denormal */ 840f9f848faSopenharmony_ci goto undfl; 841f9f848faSopenharmony_ci } 842f9f848faSopenharmony_ci } 843f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/ 844f9f848faSopenharmony_ci L = (word0(&rv) & Exp_mask) - Exp_msk1; 845f9f848faSopenharmony_ci#endif /*Sudden_Underflow}}*/ 846f9f848faSopenharmony_ci word0(&rv) = L | Bndry_mask1; 847f9f848faSopenharmony_ci word1(&rv) = 0xffffffff; 848f9f848faSopenharmony_ci#ifdef IBM 849f9f848faSopenharmony_ci goto cont; 850f9f848faSopenharmony_ci#else 851f9f848faSopenharmony_ci break; 852f9f848faSopenharmony_ci#endif 853f9f848faSopenharmony_ci } 854f9f848faSopenharmony_ci#ifndef ROUND_BIASED 855f9f848faSopenharmony_ci#ifdef Avoid_Underflow 856f9f848faSopenharmony_ci if (Lsb1) { 857f9f848faSopenharmony_ci if (!(word0(&rv) & Lsb1)) 858f9f848faSopenharmony_ci break; 859f9f848faSopenharmony_ci } 860f9f848faSopenharmony_ci else if (!(word1(&rv) & Lsb)) 861f9f848faSopenharmony_ci break; 862f9f848faSopenharmony_ci#else 863f9f848faSopenharmony_ci if (!(word1(&rv) & LSB)) 864f9f848faSopenharmony_ci break; 865f9f848faSopenharmony_ci#endif 866f9f848faSopenharmony_ci#endif 867f9f848faSopenharmony_ci if (dsign) 868f9f848faSopenharmony_ci#ifdef Avoid_Underflow 869f9f848faSopenharmony_ci dval(&rv) += sulp(&rv, scale); 870f9f848faSopenharmony_ci#else 871f9f848faSopenharmony_ci dval(&rv) += ulp(&rv); 872f9f848faSopenharmony_ci#endif 873f9f848faSopenharmony_ci#ifndef ROUND_BIASED 874f9f848faSopenharmony_ci else { 875f9f848faSopenharmony_ci#ifdef Avoid_Underflow 876f9f848faSopenharmony_ci dval(&rv) -= sulp(&rv, scale); 877f9f848faSopenharmony_ci#else 878f9f848faSopenharmony_ci dval(&rv) -= ulp(&rv); 879f9f848faSopenharmony_ci#endif 880f9f848faSopenharmony_ci#ifndef Sudden_Underflow 881f9f848faSopenharmony_ci if (!dval(&rv)) 882f9f848faSopenharmony_ci goto undfl; 883f9f848faSopenharmony_ci#endif 884f9f848faSopenharmony_ci } 885f9f848faSopenharmony_ci#ifdef Avoid_Underflow 886f9f848faSopenharmony_ci dsign = 1 - dsign; 887f9f848faSopenharmony_ci#endif 888f9f848faSopenharmony_ci#endif 889f9f848faSopenharmony_ci break; 890f9f848faSopenharmony_ci } 891f9f848faSopenharmony_ci if ((aadj = ratio(delta, bs)) <= 2.) { 892f9f848faSopenharmony_ci if (dsign) 893f9f848faSopenharmony_ci aadj = dval(&aadj1) = 1.; 894f9f848faSopenharmony_ci else if (word1(&rv) || word0(&rv) & Bndry_mask) { 895f9f848faSopenharmony_ci#ifndef Sudden_Underflow 896f9f848faSopenharmony_ci if (word1(&rv) == Tiny1 && !word0(&rv)) 897f9f848faSopenharmony_ci goto undfl; 898f9f848faSopenharmony_ci#endif 899f9f848faSopenharmony_ci aadj = 1.; 900f9f848faSopenharmony_ci dval(&aadj1) = -1.; 901f9f848faSopenharmony_ci } 902f9f848faSopenharmony_ci else { 903f9f848faSopenharmony_ci /* special case -- power of FLT_RADIX to be */ 904f9f848faSopenharmony_ci /* rounded down... */ 905f9f848faSopenharmony_ci 906f9f848faSopenharmony_ci if (aadj < 2./FLT_RADIX) 907f9f848faSopenharmony_ci aadj = 1./FLT_RADIX; 908f9f848faSopenharmony_ci else 909f9f848faSopenharmony_ci aadj *= 0.5; 910f9f848faSopenharmony_ci dval(&aadj1) = -aadj; 911f9f848faSopenharmony_ci } 912f9f848faSopenharmony_ci } 913f9f848faSopenharmony_ci else { 914f9f848faSopenharmony_ci aadj *= 0.5; 915f9f848faSopenharmony_ci dval(&aadj1) = dsign ? aadj : -aadj; 916f9f848faSopenharmony_ci#ifdef Check_FLT_ROUNDS 917f9f848faSopenharmony_ci switch(Rounding) { 918f9f848faSopenharmony_ci case 2: /* towards +infinity */ 919f9f848faSopenharmony_ci dval(&aadj1) -= 0.5; 920f9f848faSopenharmony_ci break; 921f9f848faSopenharmony_ci case 0: /* towards 0 */ 922f9f848faSopenharmony_ci case 3: /* towards -infinity */ 923f9f848faSopenharmony_ci dval(&aadj1) += 0.5; 924f9f848faSopenharmony_ci } 925f9f848faSopenharmony_ci#else 926f9f848faSopenharmony_ci if (Flt_Rounds == 0) 927f9f848faSopenharmony_ci dval(&aadj1) += 0.5; 928f9f848faSopenharmony_ci#endif /*Check_FLT_ROUNDS*/ 929f9f848faSopenharmony_ci } 930f9f848faSopenharmony_ci y = word0(&rv) & Exp_mask; 931f9f848faSopenharmony_ci 932f9f848faSopenharmony_ci /* Check for overflow */ 933f9f848faSopenharmony_ci 934f9f848faSopenharmony_ci if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { 935f9f848faSopenharmony_ci dval(&rv0) = dval(&rv); 936f9f848faSopenharmony_ci word0(&rv) -= P*Exp_msk1; 937f9f848faSopenharmony_ci dval(&adj) = dval(&aadj1) * ulp(&rv); 938f9f848faSopenharmony_ci dval(&rv) += dval(&adj); 939f9f848faSopenharmony_ci if ((word0(&rv) & Exp_mask) >= 940f9f848faSopenharmony_ci Exp_msk1*(DBL_MAX_EXP+Bias-P)) { 941f9f848faSopenharmony_ci if (word0(&rv0) == Big0 && word1(&rv0) == Big1) 942f9f848faSopenharmony_ci goto ovfl; 943f9f848faSopenharmony_ci word0(&rv) = Big0; 944f9f848faSopenharmony_ci word1(&rv) = Big1; 945f9f848faSopenharmony_ci goto cont; 946f9f848faSopenharmony_ci } 947f9f848faSopenharmony_ci else 948f9f848faSopenharmony_ci word0(&rv) += P*Exp_msk1; 949f9f848faSopenharmony_ci } 950f9f848faSopenharmony_ci else { 951f9f848faSopenharmony_ci#ifdef Avoid_Underflow 952f9f848faSopenharmony_ci if (scale && y <= 2*P*Exp_msk1) { 953f9f848faSopenharmony_ci if (aadj <= 0x7fffffff) { 954f9f848faSopenharmony_ci if ((z = aadj) <= 0) 955f9f848faSopenharmony_ci z = 1; 956f9f848faSopenharmony_ci aadj = z; 957f9f848faSopenharmony_ci dval(&aadj1) = dsign ? aadj : -aadj; 958f9f848faSopenharmony_ci } 959f9f848faSopenharmony_ci word0(&aadj1) += (2*P+1)*Exp_msk1 - y; 960f9f848faSopenharmony_ci } 961f9f848faSopenharmony_ci dval(&adj) = dval(&aadj1) * ulp(&rv); 962f9f848faSopenharmony_ci dval(&rv) += dval(&adj); 963f9f848faSopenharmony_ci#else 964f9f848faSopenharmony_ci#ifdef Sudden_Underflow 965f9f848faSopenharmony_ci if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { 966f9f848faSopenharmony_ci dval(&rv0) = dval(&rv); 967f9f848faSopenharmony_ci word0(&rv) += P*Exp_msk1; 968f9f848faSopenharmony_ci dval(&adj) = dval(&aadj1) * ulp(&rv); 969f9f848faSopenharmony_ci dval(&rv) += adj; 970f9f848faSopenharmony_ci#ifdef IBM 971f9f848faSopenharmony_ci if ((word0(&rv) & Exp_mask) < P*Exp_msk1) 972f9f848faSopenharmony_ci#else 973f9f848faSopenharmony_ci if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) 974f9f848faSopenharmony_ci#endif 975f9f848faSopenharmony_ci { 976f9f848faSopenharmony_ci if (word0(&rv0) == Tiny0 977f9f848faSopenharmony_ci && word1(&rv0) == Tiny1) 978f9f848faSopenharmony_ci goto undfl; 979f9f848faSopenharmony_ci word0(&rv) = Tiny0; 980f9f848faSopenharmony_ci word1(&rv) = Tiny1; 981f9f848faSopenharmony_ci goto cont; 982f9f848faSopenharmony_ci } 983f9f848faSopenharmony_ci else 984f9f848faSopenharmony_ci word0(&rv) -= P*Exp_msk1; 985f9f848faSopenharmony_ci } 986f9f848faSopenharmony_ci else { 987f9f848faSopenharmony_ci dval(&adj) = dval(&aadj1) * ulp(&rv); 988f9f848faSopenharmony_ci dval(&rv) += adj; 989f9f848faSopenharmony_ci } 990f9f848faSopenharmony_ci#else /*Sudden_Underflow*/ 991f9f848faSopenharmony_ci /* Compute dval(&adj) so that the IEEE rounding rules will 992f9f848faSopenharmony_ci * correctly round rv + dval(&adj) in some half-way cases. 993f9f848faSopenharmony_ci * If rv * ulp(&rv) is denormalized (i.e., 994f9f848faSopenharmony_ci * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid 995f9f848faSopenharmony_ci * trouble from bits lost to denormalization; 996f9f848faSopenharmony_ci * example: 1.2e-307 . 997f9f848faSopenharmony_ci */ 998f9f848faSopenharmony_ci if (y <= (P-1)*Exp_msk1 && aadj > 1.) { 999f9f848faSopenharmony_ci dval(&aadj1) = (double)(int)(aadj + 0.5); 1000f9f848faSopenharmony_ci if (!dsign) 1001f9f848faSopenharmony_ci dval(&aadj1) = -dval(&aadj1); 1002f9f848faSopenharmony_ci } 1003f9f848faSopenharmony_ci dval(&adj) = dval(&aadj1) * ulp(&rv); 1004f9f848faSopenharmony_ci dval(&rv) += adj; 1005f9f848faSopenharmony_ci#endif /*Sudden_Underflow*/ 1006f9f848faSopenharmony_ci#endif /*Avoid_Underflow*/ 1007f9f848faSopenharmony_ci } 1008f9f848faSopenharmony_ci z = word0(&rv) & Exp_mask; 1009f9f848faSopenharmony_ci#ifndef SET_INEXACT 1010f9f848faSopenharmony_ci#ifdef Avoid_Underflow 1011f9f848faSopenharmony_ci if (!scale) 1012f9f848faSopenharmony_ci#endif 1013f9f848faSopenharmony_ci if (y == z) { 1014f9f848faSopenharmony_ci /* Can we stop now? */ 1015f9f848faSopenharmony_ci L = (Long)aadj; 1016f9f848faSopenharmony_ci aadj -= L; 1017f9f848faSopenharmony_ci /* The tolerances below are conservative. */ 1018f9f848faSopenharmony_ci if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) { 1019f9f848faSopenharmony_ci if (aadj < .4999999 || aadj > .5000001) 1020f9f848faSopenharmony_ci break; 1021f9f848faSopenharmony_ci } 1022f9f848faSopenharmony_ci else if (aadj < .4999999/FLT_RADIX) 1023f9f848faSopenharmony_ci break; 1024f9f848faSopenharmony_ci } 1025f9f848faSopenharmony_ci#endif 1026f9f848faSopenharmony_ci cont: 1027f9f848faSopenharmony_ci Bfree(bb); 1028f9f848faSopenharmony_ci Bfree(bd); 1029f9f848faSopenharmony_ci Bfree(bs); 1030f9f848faSopenharmony_ci Bfree(delta); 1031f9f848faSopenharmony_ci } 1032f9f848faSopenharmony_ci Bfree(bb); 1033f9f848faSopenharmony_ci Bfree(bd); 1034f9f848faSopenharmony_ci Bfree(bs); 1035f9f848faSopenharmony_ci Bfree(bd0); 1036f9f848faSopenharmony_ci Bfree(delta); 1037f9f848faSopenharmony_ci#ifdef SET_INEXACT 1038f9f848faSopenharmony_ci if (inexact) { 1039f9f848faSopenharmony_ci if (!oldinexact) { 1040f9f848faSopenharmony_ci word0(&rv0) = Exp_1 + (70 << Exp_shift); 1041f9f848faSopenharmony_ci word1(&rv0) = 0; 1042f9f848faSopenharmony_ci dval(&rv0) += 1.; 1043f9f848faSopenharmony_ci } 1044f9f848faSopenharmony_ci } 1045f9f848faSopenharmony_ci else if (!oldinexact) 1046f9f848faSopenharmony_ci clear_inexact(); 1047f9f848faSopenharmony_ci#endif 1048f9f848faSopenharmony_ci#ifdef Avoid_Underflow 1049f9f848faSopenharmony_ci if (scale) { 1050f9f848faSopenharmony_ci word0(&rv0) = Exp_1 - 2*P*Exp_msk1; 1051f9f848faSopenharmony_ci word1(&rv0) = 0; 1052f9f848faSopenharmony_ci dval(&rv) *= dval(&rv0); 1053f9f848faSopenharmony_ci#ifndef NO_ERRNO 1054f9f848faSopenharmony_ci /* try to avoid the bug of testing an 8087 register value */ 1055f9f848faSopenharmony_ci#ifdef IEEE_Arith 1056f9f848faSopenharmony_ci if (!(word0(&rv) & Exp_mask)) 1057f9f848faSopenharmony_ci#else 1058f9f848faSopenharmony_ci if (word0(&rv) == 0 && word1(&rv) == 0) 1059f9f848faSopenharmony_ci#endif 1060f9f848faSopenharmony_ci errno = ERANGE; 1061f9f848faSopenharmony_ci#endif 1062f9f848faSopenharmony_ci } 1063f9f848faSopenharmony_ci#endif /* Avoid_Underflow */ 1064f9f848faSopenharmony_ci#ifdef SET_INEXACT 1065f9f848faSopenharmony_ci if (inexact && !(word0(&rv) & Exp_mask)) { 1066f9f848faSopenharmony_ci /* set underflow bit */ 1067f9f848faSopenharmony_ci dval(&rv0) = 1e-300; 1068f9f848faSopenharmony_ci dval(&rv0) *= dval(&rv0); 1069f9f848faSopenharmony_ci } 1070f9f848faSopenharmony_ci#endif 1071f9f848faSopenharmony_ci ret: 1072f9f848faSopenharmony_ci if (se) 1073f9f848faSopenharmony_ci *se = (char *)s; 1074f9f848faSopenharmony_ci return sign ? -dval(&rv) : dval(&rv); 1075f9f848faSopenharmony_ci } 1076f9f848faSopenharmony_ci 1077f9f848faSopenharmony_ci double 1078f9f848faSopenharmony_cistrtod 1079f9f848faSopenharmony_ci#ifdef KR_headers 1080f9f848faSopenharmony_ci (s00, se, loc) CONST char *s00; char **se; locale_t 1081f9f848faSopenharmony_ci#else 1082f9f848faSopenharmony_ci (CONST char *s00, char **se) 1083f9f848faSopenharmony_ci#endif 1084f9f848faSopenharmony_ci{ 1085f9f848faSopenharmony_ci return strtod_l(s00, se, 0); 1086f9f848faSopenharmony_ci} 1087f9f848faSopenharmony_ci 1088