[BACK]Return to strtod.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / gdtoa

Annotation of src/lib/libc/gdtoa/strtod.c, Revision 1.5

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

CVSweb <webmaster@jp.NetBSD.org>