tclStrToD.c

Go to the documentation of this file.
00001 /*
00002  *----------------------------------------------------------------------
00003  *
00004  * tclStrToD.c --
00005  *
00006  *      This file contains a collection of procedures for managing conversions
00007  *      to/from floating-point in Tcl. They include TclParseNumber, which
00008  *      parses numbers from strings; TclDoubleDigits, which formats numbers
00009  *      into strings of digits, and procedures for interconversion among
00010  *      'double' and 'mp_int' types.
00011  *
00012  * Copyright (c) 2005 by Kevin B. Kenny. All rights reserved.
00013  *
00014  * See the file "license.terms" for information on usage and redistribution of
00015  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
00016  *
00017  * RCS: @(#) $Id: tclStrToD.c,v 1.32 2007/12/13 15:23:20 dgp Exp $
00018  *
00019  *----------------------------------------------------------------------
00020  */
00021 
00022 #include <tclInt.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <float.h>
00026 #include <limits.h>
00027 #include <math.h>
00028 #include <ctype.h>
00029 #include <tommath.h>
00030 
00031 /*
00032  * Define KILL_OCTAL to suppress interpretation of numbers with leading zero
00033  * as octal. (Ceterum censeo: numeros octonarios delendos esse.)
00034  */
00035 
00036 #undef  KILL_OCTAL
00037 
00038 /*
00039  * This code supports (at least hypothetically), IBM, Cray, VAX and IEEE-754
00040  * floating point; of these, only IEEE-754 can represent NaN. IEEE-754 can be
00041  * uniquely determined by radix and by the widths of significand and exponent.
00042  */
00043 
00044 #if (FLT_RADIX == 2) && (DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024)
00045 #   define IEEE_FLOATING_POINT
00046 #endif
00047 
00048 /*
00049  * gcc on x86 needs access to rounding controls, because of a questionable
00050  * feature where it retains intermediate results as IEEE 'long double' values
00051  * somewhat unpredictably. It is tempting to include fpu_control.h, but that
00052  * file exists only on Linux; it is missing on Cygwin and MinGW. Most gcc-isms
00053  * and ix86-isms are factored out here.
00054  */
00055 
00056 #if defined(__GNUC__) && defined(__i386)
00057 typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
00058 #define _FPU_GETCW(cw) __asm__ __volatile__ ("fnstcw %0" : "=m" (*&cw))
00059 #define _FPU_SETCW(cw) __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw))
00060 #   define FPU_IEEE_ROUNDING    0x027f
00061 #   define ADJUST_FPU_CONTROL_WORD
00062 #endif
00063 
00064 /*
00065  * HP's PA_RISC architecture uses 7ff4000000000000 to represent a quiet NaN.
00066  * Everyone else uses 7ff8000000000000. (Why, HP, why?)
00067  */
00068 
00069 #ifdef __hppa
00070 #   define NAN_START 0x7ff4
00071 #   define NAN_MASK (((Tcl_WideUInt) 1) << 50)
00072 #else
00073 #   define NAN_START 0x7ff8
00074 #   define NAN_MASK (((Tcl_WideUInt) 1) << 51)
00075 #endif
00076 
00077 /*
00078  * Constants used by this file (most of which are only ever calculated at
00079  * runtime).
00080  */
00081 
00082 static int maxpow10_wide;       /* The powers of ten that can be represented
00083                                  * exactly as wide integers. */
00084 static Tcl_WideUInt *pow10_wide;
00085 #define MAXPOW  22
00086 static double pow10[MAXPOW+1];  /* The powers of ten that can be represented
00087                                  * exactly as IEEE754 doubles. */
00088 static int mmaxpow;             /* Largest power of ten that can be
00089                                  * represented exactly in a 'double'. */
00090 static int log10_DIGIT_MAX;     /* The number of decimal digits that fit in an
00091                                  * mp_digit. */
00092 static int log2FLT_RADIX;       /* Logarithm of the floating point radix. */
00093 static int mantBits;            /* Number of bits in a double's significand */
00094 static mp_int pow5[9];          /* Table of powers of 5**(2**n), up to
00095                                  * 5**256 */
00096 static double tiny;             /* The smallest representable double */
00097 static int maxDigits;           /* The maximum number of digits to the left of
00098                                  * the decimal point of a double. */
00099 static int minDigits;           /* The maximum number of digits to the right
00100                                  * of the decimal point in a double. */
00101 static int mantDIGIT;           /* Number of mp_digit's needed to hold the
00102                                  * significand of a double. */
00103 static const double pow_10_2_n[] = {    /* Inexact higher powers of ten. */
00104     1.0,
00105     100.0,
00106     10000.0,
00107     1.0e+8,
00108     1.0e+16,
00109     1.0e+32,
00110     1.0e+64,
00111     1.0e+128,
00112     1.0e+256
00113 };
00114 static int n770_fp;             /* Flag is 1 on Nokia N770 floating point.
00115                                  * Nokia's floating point has the words
00116                                  * reversed: if big-endian is 7654 3210,
00117                                  * and little-endian is       0123 4567,
00118                                  * then Nokia's FP is         4567 0123;
00119                                  * little-endian within the 32-bit words
00120                                  * but big-endian between them. */
00121 
00122 /*
00123  * Static functions defined in this file.
00124  */
00125 
00126 static double           AbsoluteValue(double v, int *signum);
00127 static int              AccumulateDecimalDigit(unsigned, int, 
00128                             Tcl_WideUInt *, mp_int *, int);
00129 static double           BignumToBiasedFrExp(mp_int *big, int* machexp);
00130 static int              GetIntegerTimesPower(double v, mp_int *r, int *e);
00131 static double           MakeHighPrecisionDouble(int signum,
00132                             mp_int *significand, int nSigDigs, int exponent);
00133 static double           MakeLowPrecisionDouble(int signum,
00134                             Tcl_WideUInt significand, int nSigDigs,
00135                             int exponent);
00136 static double           MakeNaN(int signum, Tcl_WideUInt tag);
00137 static Tcl_WideUInt     Nokia770Twiddle(Tcl_WideUInt w);
00138 static double           Pow10TimesFrExp(int exponent, double fraction,
00139                             int *machexp);
00140 static double           RefineApproximation(double approx,
00141                             mp_int *exactSignificand, int exponent);
00142 static double           SafeLdExp(double fraction, int exponent);
00143 
00144 /*
00145  *----------------------------------------------------------------------
00146  *
00147  * TclParseNumber --
00148  *
00149  *      Scans bytes, interpreted as characters in Tcl's internal encoding, and
00150  *      parses the longest prefix that is the string representation of a
00151  *      number in a format recognized by Tcl.
00152  *
00153  *      The arguments bytes, numBytes, and objPtr are the inputs which
00154  *      determine the string to be parsed. If bytes is non-NULL, it points to
00155  *      the first byte to be scanned. If bytes is NULL, then objPtr must be
00156  *      non-NULL, and the string representation of objPtr will be scanned
00157  *      (generated first, if necessary). The numBytes argument determines the
00158  *      number of bytes to be scanned. If numBytes is negative, the first NUL
00159  *      byte encountered will terminate the scan. If numBytes is non-negative,
00160  *      then no more than numBytes bytes will be scanned.
00161  *
00162  *      The argument flags is an input that controls the numeric formats
00163  *      recognized by the parser. The flag bits are:
00164  *
00165  *      - TCL_PARSE_INTEGER_ONLY:       accept only integer values; reject
00166  *              strings that denote floating point values (or accept only the
00167  *              leading portion of them that are integer values).
00168  *      - TCL_PARSE_SCAN_PREFIXES:      ignore the prefixes 0b and 0o that are
00169  *              not part of the [scan] command's vocabulary. Use only in
00170  *              combination with TCL_PARSE_INTEGER_ONLY.
00171  *      - TCL_PARSE_OCTAL_ONLY:         parse only in the octal format, whether
00172  *              or not a prefix is present that would lead to octal parsing.
00173  *              Use only in combination with TCL_PARSE_INTEGER_ONLY.
00174  *      - TCL_PARSE_HEXADECIMAL_ONLY:   parse only in the hexadecimal format,
00175  *              whether or not a prefix is present that would lead to
00176  *              hexadecimal parsing. Use only in combination with
00177  *              TCL_PARSE_INTEGER_ONLY.
00178  *      - TCL_PARSE_DECIMAL_ONLY:       parse only in the decimal format, no
00179  *              matter whether a 0 prefix would normally force a different
00180  *              base.
00181  *      - TCL_PARSE_NO_WHITESPACE:      reject any leading/trailing whitespace
00182  *
00183  *      The arguments interp and expected are inputs that control error
00184  *      message generation. If interp is NULL, no error message will be
00185  *      generated. If interp is non-NULL, then expected must also be non-NULL.
00186  *      When TCL_ERROR is returned, an error message will be left in the
00187  *      result of interp, and the expected argument will appear in the error
00188  *      message as the thing TclParseNumber expected, but failed to find in
00189  *      the string.
00190  *
00191  *      The arguments objPtr and endPtrPtr as well as the return code are the
00192  *      outputs.
00193  *
00194  *      When the parser cannot find any prefix of the string that matches a
00195  *      format it is looking for, TCL_ERROR is returned and an error message
00196  *      may be generated and returned as described above. The contents of
00197  *      objPtr will not be changed. If endPtrPtr is non-NULL, a pointer to the
00198  *      character in the string that terminated the scan will be written to
00199  *      *endPtrPtr.
00200  *
00201  *      When the parser determines that the entire string matches a format it
00202  *      is looking for, TCL_OK is returned, and if objPtr is non-NULL, then
00203  *      the internal rep and Tcl_ObjType of objPtr are set to the "canonical"
00204  *      numeric value that matches the scanned string. If endPtrPtr is not
00205  *      NULL, a pointer to the end of the string will be written to *endPtrPtr
00206  *      (that is, either bytes+numBytes or a pointer to a terminating NUL
00207  *      byte).
00208  *
00209  *      When the parser determines that a partial string matches a format it
00210  *      is looking for, the value of endPtrPtr determines what happens:
00211  *
00212  *      - If endPtrPtr is NULL, then TCL_ERROR is returned, with error message
00213  *              generation as above.
00214  *
00215  *      - If endPtrPtr is non-NULL, then TCL_OK is returned and objPtr
00216  *              internals are set as above. Also, a pointer to the first
00217  *              character following the parsed numeric string is written to
00218  *              *endPtrPtr.
00219  *
00220  *      In some cases where the string being scanned is the string rep of
00221  *      objPtr, this routine can leave objPtr in an inconsistent state where
00222  *      its string rep and its internal rep do not agree. In these cases the
00223  *      internal rep will be in agreement with only some substring of the
00224  *      string rep. This might happen if the caller passes in a non-NULL bytes
00225  *      value that points somewhere into the string rep. It might happen if
00226  *      the caller passes in a numBytes value that limits the scan to only a
00227  *      prefix of the string rep. Or it might happen if a non-NULL value of
00228  *      endPtrPtr permits a TCL_OK return from only a partial string match. It
00229  *      is the responsibility of the caller to detect and correct such
00230  *      inconsistencies when they can and do arise.
00231  *
00232  * Results:
00233  *      Returns a standard Tcl result.
00234  *
00235  * Side effects:
00236  *      The string representaton of objPtr may be generated.
00237  *
00238  *      The internal representation and Tcl_ObjType of objPtr may be changed.
00239  *      This may involve allocation and/or freeing of memory.
00240  *
00241  *----------------------------------------------------------------------
00242  */
00243 
00244 int
00245 TclParseNumber(
00246     Tcl_Interp *interp,         /* Used for error reporting. May be NULL. */
00247     Tcl_Obj *objPtr,            /* Object to receive the internal rep. */
00248     const char *expected,       /* Description of the type of number the
00249                                  * caller expects to be able to parse
00250                                  * ("integer", "boolean value", etc.). */
00251     const char *bytes,          /* Pointer to the start of the string to
00252                                  * scan. */
00253     int numBytes,               /* Maximum number of bytes to scan, see
00254                                  * above. */
00255     const char **endPtrPtr,     /* Place to store pointer to the character
00256                                  * that terminated the scan. */
00257     int flags)                  /* Flags governing the parse. */
00258 {
00259     enum State {
00260         INITIAL, SIGNUM, ZERO, ZERO_X,
00261         ZERO_O, ZERO_B, BINARY,
00262         HEXADECIMAL, OCTAL, BAD_OCTAL, DECIMAL,
00263         LEADING_RADIX_POINT, FRACTION,
00264         EXPONENT_START, EXPONENT_SIGNUM, EXPONENT,
00265         sI, sIN, sINF, sINFI, sINFIN, sINFINI, sINFINIT, sINFINITY
00266 #ifdef IEEE_FLOATING_POINT
00267         , sN, sNA, sNAN, sNANPAREN, sNANHEX, sNANFINISH
00268 #endif
00269     } state = INITIAL;
00270     enum State acceptState = INITIAL;
00271 
00272     int signum = 0;             /* Sign of the number being parsed */
00273     Tcl_WideUInt significandWide = 0;
00274                                 /* Significand of the number being parsed (if
00275                                  * no overflow) */
00276     mp_int significandBig;      /* Significand of the number being parsed (if
00277                                  * it overflows significandWide) */
00278     int significandOverflow = 0;/* Flag==1 iff significandBig is used */
00279     Tcl_WideUInt octalSignificandWide = 0;
00280                                 /* Significand of an octal number; needed
00281                                  * because we don't know whether a number with
00282                                  * a leading zero is octal or decimal until
00283                                  * we've scanned forward to a '.' or 'e' */
00284     mp_int octalSignificandBig; /* Significand of octal number once
00285                                  * octalSignificandWide overflows */
00286     int octalSignificandOverflow = 0;
00287                                 /* Flag==1 if octalSignificandBig is used */
00288     int numSigDigs = 0;         /* Number of significant digits in the decimal
00289                                  * significand */
00290     int numTrailZeros = 0;      /* Number of trailing zeroes at the current
00291                                  * point in the parse. */
00292     int numDigitsAfterDp = 0;   /* Number of digits scanned after the decimal
00293                                  * point */
00294     int exponentSignum = 0;     /* Signum of the exponent of a floating point
00295                                  * number */
00296     long exponent = 0;          /* Exponent of a floating point number */
00297     const char *p;              /* Pointer to next character to scan */
00298     size_t len;                 /* Number of characters remaining after p */
00299     const char *acceptPoint;    /* Pointer to position after last character in
00300                                  * an acceptable number */
00301     size_t acceptLen;           /* Number of characters following that
00302                                  * point. */
00303     int status = TCL_OK;        /* Status to return to caller */
00304     char d = 0;                 /* Last hexadecimal digit scanned; initialized
00305                                  * to avoid a compiler warning. */
00306     int shift = 0;              /* Amount to shift when accumulating binary */
00307     int explicitOctal = 0;
00308 
00309 #define ALL_BITS        (~(Tcl_WideUInt)0)
00310 #define MOST_BITS       (ALL_BITS >> 1)
00311 
00312     /*
00313      * Initialize bytes to start of the object's string rep if the caller
00314      * didn't pass anything else.
00315      */
00316 
00317     if (bytes == NULL) {
00318         bytes = TclGetString(objPtr);
00319     }
00320 
00321     p = bytes;
00322     len = numBytes;
00323     acceptPoint = p;
00324     acceptLen = len;
00325     while (1) {
00326         char c = len ? *p : '\0';
00327         switch (state) {
00328 
00329         case INITIAL:
00330             /*
00331              * Initial state. Acceptable characters are +, -, digits, period,
00332              * I, N, and whitespace.
00333              */
00334 
00335             if (isspace(UCHAR(c))) {
00336                 if (flags & TCL_PARSE_NO_WHITESPACE) {
00337                     goto endgame;
00338                 }
00339                 break;
00340             } else if (c == '+') {
00341                 state = SIGNUM;
00342                 break;
00343             } else if (c == '-') {
00344                 signum = 1;
00345                 state = SIGNUM;
00346                 break;
00347             }
00348             /* FALLTHROUGH */
00349 
00350         case SIGNUM:
00351             /*
00352              * Scanned a leading + or -. Acceptable characters are digits,
00353              * period, I, and N.
00354              */
00355 
00356             if (c == '0') {
00357                 if (flags & TCL_PARSE_DECIMAL_ONLY) {
00358                     state = DECIMAL;
00359                 } else {
00360                     state = ZERO;
00361                 }
00362                 break;
00363             } else if (flags & TCL_PARSE_HEXADECIMAL_ONLY) {
00364                 goto zerox;
00365             } else if (flags & TCL_PARSE_OCTAL_ONLY) {
00366                 goto zeroo;
00367             } else if (isdigit(UCHAR(c))) {
00368                 significandWide = c - '0';
00369                 numSigDigs = 1;
00370                 state = DECIMAL;
00371                 break;
00372             } else if (flags & TCL_PARSE_INTEGER_ONLY) {
00373                 goto endgame;
00374             } else if (c == '.') {
00375                 state = LEADING_RADIX_POINT;
00376                 break;
00377             } else if (c == 'I' || c == 'i') {
00378                 state = sI;
00379                 break;
00380 #ifdef IEEE_FLOATING_POINT
00381             } else if (c == 'N' || c == 'n') {
00382                 state = sN;
00383                 break;
00384 #endif
00385             }
00386             goto endgame;
00387 
00388         case ZERO:
00389             /*
00390              * Scanned a leading zero (perhaps with a + or -). Acceptable
00391              * inputs are digits, period, X, and E. If 8 or 9 is encountered,
00392              * the number can't be octal. This state and the OCTAL state
00393              * differ only in whether they recognize 'X'.
00394              */
00395 
00396             acceptState = state;
00397             acceptPoint = p;
00398             acceptLen = len;
00399             if (c == 'x' || c == 'X') {
00400                 state = ZERO_X;
00401                 break;
00402             }
00403             if (flags & TCL_PARSE_HEXADECIMAL_ONLY) {
00404                 goto zerox;
00405             }
00406             if (flags & TCL_PARSE_SCAN_PREFIXES) {
00407                 goto zeroo;
00408             }
00409             if (c == 'b' || c == 'B') {
00410                 state = ZERO_B;
00411                 break;
00412             }
00413             if (c == 'o' || c == 'O') {
00414                 explicitOctal = 1;
00415                 state = ZERO_O;
00416                 break;
00417             }
00418 #ifdef KILL_OCTAL
00419             goto decimal;
00420 #endif
00421             /* FALLTHROUGH */
00422 
00423         case OCTAL:
00424             /*
00425              * Scanned an optional + or -, followed by a string of octal
00426              * digits. Acceptable inputs are more digits, period, or E. If 8
00427              * or 9 is encountered, commit to floating point.
00428              */
00429 
00430             acceptState = state;
00431             acceptPoint = p;
00432             acceptLen = len;
00433             /* FALLTHROUGH */
00434         case ZERO_O:
00435         zeroo:
00436             if (c == '0') {
00437                 ++numTrailZeros;
00438                 state = OCTAL;
00439                 break;
00440             } else if (c >= '1' && c <= '7') {
00441                 if (objPtr != NULL) {
00442                     shift = 3 * (numTrailZeros + 1);
00443                     significandOverflow = AccumulateDecimalDigit(
00444                             (unsigned)(c-'0'), numTrailZeros,
00445                             &significandWide, &significandBig,
00446                             significandOverflow);
00447 
00448                     if (!octalSignificandOverflow) {
00449                         /*
00450                          * Shifting by more bits than are in the value being
00451                          * shifted is at least de facto nonportable. Check for
00452                          * too large shifts first.
00453                          */
00454 
00455                         if ((octalSignificandWide != 0)
00456                                 && (((size_t)shift >=
00457                                         CHAR_BIT*sizeof(Tcl_WideUInt))
00458                                 || (octalSignificandWide >
00459                                         (~(Tcl_WideUInt)0 >> shift)))) {
00460                             octalSignificandOverflow = 1;
00461                             TclBNInitBignumFromWideUInt(&octalSignificandBig,
00462                                     octalSignificandWide);
00463                         }
00464                     }
00465                     if (!octalSignificandOverflow) {
00466                         octalSignificandWide =
00467                                 (octalSignificandWide << shift) + (c - '0');
00468                     } else {
00469                         mp_mul_2d(&octalSignificandBig, shift,
00470                                 &octalSignificandBig);
00471                         mp_add_d(&octalSignificandBig, (mp_digit)(c - '0'),
00472                                 &octalSignificandBig);
00473                     }
00474                 }
00475                 if (numSigDigs != 0) {
00476                     numSigDigs += numTrailZeros+1;
00477                 } else {
00478                     numSigDigs = 1;
00479                 }
00480                 numTrailZeros = 0;
00481                 state = OCTAL;
00482                 break;
00483             }
00484             /* FALLTHROUGH */
00485 
00486         case BAD_OCTAL:
00487             if (explicitOctal) {
00488                 /*
00489                  * No forgiveness for bad digits in explicitly octal numbers.
00490                  */
00491 
00492                 goto endgame;
00493             }
00494             if (flags & TCL_PARSE_INTEGER_ONLY) {
00495                 /*
00496                  * No seeking floating point when parsing only integer.
00497                  */
00498 
00499                 goto endgame;
00500             }
00501 #ifndef KILL_OCTAL
00502 
00503             /*
00504              * Scanned a number with a leading zero that contains an 8, 9,
00505              * radix point or E. This is an invalid octal number, but might
00506              * still be floating point.
00507              */
00508 
00509             if (c == '0') {
00510                 ++numTrailZeros;
00511                 state = BAD_OCTAL;
00512                 break;
00513             } else if (isdigit(UCHAR(c))) {
00514                 if (objPtr != NULL) {
00515                     significandOverflow = AccumulateDecimalDigit(
00516                             (unsigned)(c-'0'), numTrailZeros,
00517                             &significandWide, &significandBig,
00518                             significandOverflow);
00519                 }
00520                 if (numSigDigs != 0) {
00521                     numSigDigs += (numTrailZeros + 1);
00522                 } else {
00523                     numSigDigs = 1;
00524                 }
00525                 numTrailZeros = 0;
00526                 state = BAD_OCTAL;
00527                 break;
00528             } else if (c == '.') {
00529                 state = FRACTION;
00530                 break;
00531             } else if (c == 'E' || c == 'e') {
00532                 state = EXPONENT_START;
00533                 break;
00534             }
00535 #endif
00536             goto endgame;
00537 
00538             /*
00539              * Scanned 0x. If state is HEXADECIMAL, scanned at least one
00540              * character following the 0x. The only acceptable inputs are
00541              * hexadecimal digits.
00542              */
00543 
00544         case HEXADECIMAL:
00545             acceptState = state;
00546             acceptPoint = p;
00547             acceptLen = len;
00548             /* FALLTHROUGH */
00549 
00550         case ZERO_X:
00551         zerox:
00552             if (c == '0') {
00553                 ++numTrailZeros;
00554                 state = HEXADECIMAL;
00555                 break;
00556             } else if (isdigit(UCHAR(c))) {
00557                 d = (c-'0');
00558             } else if (c >= 'A' && c <= 'F') {
00559                 d = (c-'A'+10);
00560             } else if (c >= 'a' && c <= 'f') {
00561                 d = (c-'a'+10);
00562             } else {
00563                 goto endgame;
00564             }
00565             if (objPtr != NULL) {
00566                 shift = 4 * (numTrailZeros + 1);
00567                 if (!significandOverflow) {
00568                     /*
00569                      * Shifting by more bits than are in the value being
00570                      * shifted is at least de facto nonportable. Check for too
00571                      * large shifts first.
00572                      */
00573 
00574                     if (significandWide != 0 &&
00575                             ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
00576                             significandWide > (~(Tcl_WideUInt)0 >> shift))) {
00577                         significandOverflow = 1;
00578                         TclBNInitBignumFromWideUInt(&significandBig,
00579                                 significandWide);
00580                     }
00581                 }
00582                 if (!significandOverflow) {
00583                     significandWide = (significandWide << shift) + d;
00584                 } else {
00585                     mp_mul_2d(&significandBig, shift, &significandBig);
00586                     mp_add_d(&significandBig, (mp_digit) d, &significandBig);
00587                 }
00588             }
00589             numTrailZeros = 0;
00590             state = HEXADECIMAL;
00591             break;
00592 
00593         case BINARY:
00594             acceptState = state;
00595             acceptPoint = p;
00596             acceptLen = len;
00597         case ZERO_B:
00598             if (c == '0') {
00599                 ++numTrailZeros;
00600                 state = BINARY;
00601                 break;
00602             } else if (c != '1') {
00603                 goto endgame;
00604             }
00605             if (objPtr != NULL) {
00606                 shift = numTrailZeros + 1;
00607                 if (!significandOverflow) {
00608                     /*
00609                      * Shifting by more bits than are in the value being
00610                      * shifted is at least de facto nonportable. Check for too
00611                      * large shifts first.
00612                      */
00613 
00614                     if (significandWide != 0 &&
00615                             ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
00616                             significandWide > (~(Tcl_WideUInt)0 >> shift))) {
00617                         significandOverflow = 1;
00618                         TclBNInitBignumFromWideUInt(&significandBig,
00619                                 significandWide);
00620                     }
00621                 }
00622                 if (!significandOverflow) {
00623                     significandWide = (significandWide << shift) + 1;
00624                 } else {
00625                     mp_mul_2d(&significandBig, shift, &significandBig);
00626                     mp_add_d(&significandBig, (mp_digit) 1, &significandBig);
00627                 }
00628             }
00629             numTrailZeros = 0;
00630             state = BINARY;
00631             break;
00632 
00633         case DECIMAL:
00634             /*
00635              * Scanned an optional + or - followed by a string of decimal
00636              * digits.
00637              */
00638 
00639 #ifdef KILL_OCTAL
00640         decimal:
00641 #endif
00642             acceptState = state;
00643             acceptPoint = p;
00644             acceptLen = len;
00645             if (c == '0') {
00646                 ++numTrailZeros;
00647                 state = DECIMAL;
00648                 break;
00649             } else if (isdigit(UCHAR(c))) {
00650                 if (objPtr != NULL) {
00651                     significandOverflow = AccumulateDecimalDigit(
00652                             (unsigned)(c - '0'), numTrailZeros,
00653                             &significandWide, &significandBig,
00654                             significandOverflow);
00655                 }
00656                 numSigDigs += numTrailZeros+1;
00657                 numTrailZeros = 0;
00658                 state = DECIMAL;
00659                 break;
00660             } else if (flags & TCL_PARSE_INTEGER_ONLY) {
00661                 goto endgame;
00662             } else if (c == '.') {
00663                 state = FRACTION;
00664                 break;
00665             } else if (c == 'E' || c == 'e') {
00666                 state = EXPONENT_START;
00667                 break;
00668             }
00669             goto endgame;
00670 
00671             /*
00672              * Found a decimal point. If no digits have yet been scanned, E is
00673              * not allowed; otherwise, it introduces the exponent. If at least
00674              * one digit has been found, we have a possible complete number.
00675              */
00676 
00677         case FRACTION:
00678             acceptState = state;
00679             acceptPoint = p;
00680             acceptLen = len;
00681             if (c == 'E' || c=='e') {
00682                 state = EXPONENT_START;
00683                 break;
00684             }
00685             /* FALLTHROUGH */
00686 
00687         case LEADING_RADIX_POINT:
00688             if (c == '0') {
00689                 ++numDigitsAfterDp;
00690                 ++numTrailZeros;
00691                 state = FRACTION;
00692                 break;
00693             } else if (isdigit(UCHAR(c))) {
00694                 ++numDigitsAfterDp;
00695                 if (objPtr != NULL) {
00696                     significandOverflow = AccumulateDecimalDigit(
00697                             (unsigned)(c-'0'), numTrailZeros,
00698                             &significandWide, &significandBig,
00699                             significandOverflow);
00700                 }
00701                 if (numSigDigs != 0) {
00702                     numSigDigs += numTrailZeros+1;
00703                 } else {
00704                     numSigDigs = 1;
00705                 }
00706                 numTrailZeros = 0;
00707                 state = FRACTION;
00708                 break;
00709             }
00710             goto endgame;
00711 
00712         case EXPONENT_START:
00713             /*
00714              * Scanned the E at the start of an exponent. Make sure a legal
00715              * character follows before using the C library strtol routine,
00716              * which allows whitespace.
00717              */
00718 
00719             if (c == '+') {
00720                 state = EXPONENT_SIGNUM;
00721                 break;
00722             } else if (c == '-') {
00723                 exponentSignum = 1;
00724                 state = EXPONENT_SIGNUM;
00725                 break;
00726             }
00727             /* FALLTHROUGH */
00728 
00729         case EXPONENT_SIGNUM:
00730             /*
00731              * Found the E at the start of the exponent, followed by a sign
00732              * character.
00733              */
00734 
00735             if (isdigit(UCHAR(c))) {
00736                 exponent = c - '0';
00737                 state = EXPONENT;
00738                 break;
00739             }
00740             goto endgame;
00741 
00742         case EXPONENT:
00743             /*
00744              * Found an exponent with at least one digit. Accumulate it,
00745              * making sure to hard-pin it to LONG_MAX on overflow.
00746              */
00747 
00748             acceptState = state;
00749             acceptPoint = p;
00750             acceptLen = len;
00751             if (isdigit(UCHAR(c))) {
00752                 if (exponent < (LONG_MAX - 9) / 10) {
00753                     exponent = 10 * exponent + (c - '0');
00754                 } else {
00755                     exponent = LONG_MAX;
00756                 }
00757                 state = EXPONENT;
00758                 break;
00759             }
00760             goto endgame;
00761 
00762             /*
00763              * Parse out INFINITY by simply spelling it out. INF is accepted
00764              * as an abbreviation; other prefices are not.
00765              */
00766 
00767         case sI:
00768             if (c == 'n' || c == 'N') {
00769                 state = sIN;
00770                 break;
00771             }
00772             goto endgame;
00773         case sIN:
00774             if (c == 'f' || c == 'F') {
00775                 state = sINF;
00776                 break;
00777             }
00778             goto endgame;
00779         case sINF:
00780             acceptState = state;
00781             acceptPoint = p;
00782             acceptLen = len;
00783             if (c == 'i' || c == 'I') {
00784                 state = sINFI;
00785                 break;
00786             }
00787             goto endgame;
00788         case sINFI:
00789             if (c == 'n' || c == 'N') {
00790                 state = sINFIN;
00791                 break;
00792             }
00793             goto endgame;
00794         case sINFIN:
00795             if (c == 'i' || c == 'I') {
00796                 state = sINFINI;
00797                 break;
00798             }
00799             goto endgame;
00800         case sINFINI:
00801             if (c == 't' || c == 'T') {
00802                 state = sINFINIT;
00803                 break;
00804             }
00805             goto endgame;
00806         case sINFINIT:
00807             if (c == 'y' || c == 'Y') {
00808                 state = sINFINITY;
00809                 break;
00810             }
00811             goto endgame;
00812 
00813             /*
00814              * Parse NaN's.
00815              */
00816 #ifdef IEEE_FLOATING_POINT
00817         case sN:
00818             if (c == 'a' || c == 'A') {
00819                 state = sNA;
00820                 break;
00821             }
00822             goto endgame;
00823         case sNA:
00824             if (c == 'n' || c == 'N') {
00825                 state = sNAN;
00826                 break;
00827             }
00828             goto endgame;
00829         case sNAN:
00830             acceptState = state;
00831             acceptPoint = p;
00832             acceptLen = len;
00833             if (c == '(') {
00834                 state = sNANPAREN;
00835                 break;
00836             }
00837             goto endgame;
00838 
00839             /*
00840              * Parse NaN(hexdigits)
00841              */
00842         case sNANHEX:
00843             if (c == ')') {
00844                 state = sNANFINISH;
00845                 break;
00846             }
00847             /* FALLTHROUGH */
00848         case sNANPAREN:
00849             if (isspace(UCHAR(c))) {
00850                 break;
00851             }
00852             if (numSigDigs < 13) {
00853                 if (c >= '0' && c <= '9') {
00854                     d = c - '0';
00855                 } else if (c >= 'a' && c <= 'f') {
00856                     d = 10 + c - 'a';
00857                 } else if (c >= 'A' && c <= 'F') {
00858                     d = 10 + c - 'A';
00859                 }
00860                 significandWide = (significandWide << 4) + d;
00861                 state = sNANHEX;
00862                 break;
00863             }
00864             goto endgame;
00865         case sNANFINISH:
00866 #endif
00867 
00868         case sINFINITY:
00869             acceptState = state;
00870             acceptPoint = p;
00871             acceptLen = len;
00872             goto endgame;
00873         }
00874         ++p;
00875         --len;
00876     }
00877 
00878   endgame:
00879     if (acceptState == INITIAL) {
00880         /*
00881          * No numeric string at all found.
00882          */
00883 
00884         status = TCL_ERROR;
00885         if (endPtrPtr != NULL) {
00886             *endPtrPtr = p;
00887         }
00888     } else {
00889         /*
00890          * Back up to the last accepting state in the lexer.
00891          */
00892 
00893         p = acceptPoint;
00894         len = acceptLen;
00895         if (!(flags & TCL_PARSE_NO_WHITESPACE)) {
00896             /*
00897              * Accept trailing whitespace.
00898              */
00899 
00900             while (len != 0 && isspace(UCHAR(*p))) {
00901                 ++p;
00902                 --len;
00903             }
00904         }
00905         if (endPtrPtr == NULL) {
00906             if ((len != 0) && ((numBytes > 0) || (*p != '\0'))) {
00907                 status = TCL_ERROR;
00908             }
00909         } else {
00910             *endPtrPtr = p;
00911         }
00912     }
00913 
00914     /*
00915      * Generate and store the appropriate internal rep.
00916      */
00917 
00918     if (status == TCL_OK && objPtr != NULL) {
00919         TclFreeIntRep(objPtr);
00920         switch (acceptState) {
00921         case SIGNUM:
00922         case BAD_OCTAL:
00923         case ZERO_X:
00924         case ZERO_O:
00925         case ZERO_B:
00926         case LEADING_RADIX_POINT:
00927         case EXPONENT_START:
00928         case EXPONENT_SIGNUM:
00929         case sI:
00930         case sIN:
00931         case sINFI:
00932         case sINFIN:
00933         case sINFINI:
00934         case sINFINIT:
00935         case sN:
00936         case sNA:
00937         case sNANPAREN:
00938         case sNANHEX:
00939             Tcl_Panic("TclParseNumber: bad acceptState %d parsing '%s'",
00940                     acceptState, bytes);
00941 
00942         case BINARY:
00943             shift = numTrailZeros;
00944             if (!significandOverflow && significandWide != 0 &&
00945                     ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
00946                     significandWide > (MOST_BITS + signum) >> shift)) {
00947                 significandOverflow = 1;
00948                 TclBNInitBignumFromWideUInt(&significandBig, significandWide);
00949             }
00950             if (shift) {
00951                 if (!significandOverflow) {
00952                     significandWide <<= shift;
00953                 } else {
00954                     mp_mul_2d(&significandBig, shift, &significandBig);
00955                 }
00956             }
00957             goto returnInteger;
00958 
00959         case HEXADECIMAL:
00960             /*
00961              * Returning a hex integer. Final scaling step.
00962              */
00963 
00964             shift = 4 * numTrailZeros;
00965             if (!significandOverflow && significandWide !=0 &&
00966                     ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
00967                     significandWide > (MOST_BITS + signum) >> shift)) {
00968                 significandOverflow = 1;
00969                 TclBNInitBignumFromWideUInt(&significandBig, significandWide);
00970             }
00971             if (shift) {
00972                 if (!significandOverflow) {
00973                     significandWide <<= shift;
00974                 } else {
00975                     mp_mul_2d(&significandBig, shift, &significandBig);
00976                 }
00977             }
00978             goto returnInteger;
00979 
00980         case OCTAL:
00981             /*
00982              * Returning an octal integer. Final scaling step
00983              */
00984 
00985             shift = 3 * numTrailZeros;
00986             if (!octalSignificandOverflow && octalSignificandWide != 0 &&
00987                     ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
00988                     octalSignificandWide > (MOST_BITS + signum) >> shift)) {
00989                 octalSignificandOverflow = 1;
00990                 TclBNInitBignumFromWideUInt(&octalSignificandBig,
00991                         octalSignificandWide);
00992             }
00993             if (shift) {
00994                 if (!octalSignificandOverflow) {
00995                     octalSignificandWide <<= shift;
00996                 } else {
00997                     mp_mul_2d(&octalSignificandBig, shift,
00998                             &octalSignificandBig);
00999                 }
01000             }
01001             if (!octalSignificandOverflow) {
01002                 if (octalSignificandWide >
01003                         (Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
01004 #ifndef NO_WIDE_TYPE
01005                     if (octalSignificandWide <= (MOST_BITS + signum)) {
01006                         objPtr->typePtr = &tclWideIntType;
01007                         if (signum) {
01008                             objPtr->internalRep.wideValue =
01009                                     - (Tcl_WideInt) octalSignificandWide;
01010                         } else {
01011                             objPtr->internalRep.wideValue =
01012                                     (Tcl_WideInt) octalSignificandWide;
01013                         }
01014                         break;
01015                     }
01016 #endif
01017                     TclBNInitBignumFromWideUInt(&octalSignificandBig,
01018                             octalSignificandWide);
01019                     octalSignificandOverflow = 1;
01020                 } else {
01021                     objPtr->typePtr = &tclIntType;
01022                     if (signum) {
01023                         objPtr->internalRep.longValue =
01024                                 - (long) octalSignificandWide;
01025                     } else {
01026                         objPtr->internalRep.longValue =
01027                                 (long) octalSignificandWide;
01028                     }
01029                 }
01030             }
01031             if (octalSignificandOverflow) {
01032                 if (signum) {
01033                     mp_neg(&octalSignificandBig, &octalSignificandBig);
01034                 }
01035                 TclSetBignumIntRep(objPtr, &octalSignificandBig);
01036             }
01037             break;
01038 
01039         case ZERO:
01040         case DECIMAL:
01041             significandOverflow = AccumulateDecimalDigit(0, numTrailZeros-1,
01042                     &significandWide, &significandBig, significandOverflow);
01043             if (!significandOverflow && (significandWide > MOST_BITS+signum)) {
01044                 significandOverflow = 1;
01045                 TclBNInitBignumFromWideUInt(&significandBig, significandWide);
01046             }
01047         returnInteger:
01048             if (!significandOverflow) {
01049                 if (significandWide >
01050                         (Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
01051 #ifndef NO_WIDE_TYPE
01052                     if (significandWide <= MOST_BITS+signum) {
01053                         objPtr->typePtr = &tclWideIntType;
01054                         if (signum) {
01055                             objPtr->internalRep.wideValue =
01056                                     - (Tcl_WideInt) significandWide;
01057                         } else {
01058                             objPtr->internalRep.wideValue =
01059                                     (Tcl_WideInt) significandWide;
01060                         }
01061                         break;
01062                     }
01063 #endif
01064                     TclBNInitBignumFromWideUInt(&significandBig,
01065                             significandWide);
01066                     significandOverflow = 1;
01067                 } else {
01068                     objPtr->typePtr = &tclIntType;
01069                     if (signum) {
01070                         objPtr->internalRep.longValue =
01071                                 - (long) significandWide;
01072                     } else {
01073                         objPtr->internalRep.longValue =
01074                                 (long) significandWide;
01075                     }
01076                 }
01077             }
01078             if (significandOverflow) {
01079                 if (signum) {
01080                     mp_neg(&significandBig, &significandBig);
01081                 }
01082                 TclSetBignumIntRep(objPtr, &significandBig);
01083             }
01084             break;
01085 
01086         case FRACTION:
01087         case EXPONENT:
01088 
01089             /*
01090              * Here, we're parsing a floating-point number. 'significandWide'
01091              * or 'significandBig' contains the exact significand, according
01092              * to whether 'significandOverflow' is set. The desired floating
01093              * point value is significand * 10**k, where
01094              * k = numTrailZeros+exponent-numDigitsAfterDp.
01095              */
01096 
01097             objPtr->typePtr = &tclDoubleType;
01098             if (exponentSignum) {
01099                 exponent = - exponent;
01100             }
01101             if (!significandOverflow) {
01102                 objPtr->internalRep.doubleValue = MakeLowPrecisionDouble(
01103                         signum, significandWide, numSigDigs,
01104                         (numTrailZeros + exponent - numDigitsAfterDp));
01105             } else {
01106                 objPtr->internalRep.doubleValue = MakeHighPrecisionDouble(
01107                         signum, &significandBig, numSigDigs,
01108                         (numTrailZeros + exponent - numDigitsAfterDp));
01109             }
01110             break;
01111 
01112         case sINF:
01113         case sINFINITY:
01114             if (signum) {
01115                 objPtr->internalRep.doubleValue = -HUGE_VAL;
01116             } else {
01117                 objPtr->internalRep.doubleValue = HUGE_VAL;
01118             }
01119             objPtr->typePtr = &tclDoubleType;
01120             break;
01121 
01122         case sNAN:
01123         case sNANFINISH:
01124             objPtr->internalRep.doubleValue = MakeNaN(signum, significandWide);
01125             objPtr->typePtr = &tclDoubleType;
01126             break;
01127 
01128         case INITIAL:
01129             /* This case only to silence compiler warning */
01130             Tcl_Panic("TclParseNumber: state INITIAL can't happen here");
01131         }
01132     }
01133 
01134     /*
01135      * Format an error message when an invalid number is encountered.
01136      */
01137 
01138     if (status != TCL_OK) {
01139         if (interp != NULL) {
01140             Tcl_Obj *msg;
01141 
01142             TclNewLiteralStringObj(msg, "expected ");
01143             Tcl_AppendToObj(msg, expected, -1);
01144             Tcl_AppendToObj(msg, " but got \"", -1);
01145             Tcl_AppendLimitedToObj(msg, bytes, numBytes, 50, "");
01146             Tcl_AppendToObj(msg, "\"", -1);
01147             if (state == BAD_OCTAL) {
01148                 Tcl_AppendToObj(msg, " (looks like invalid octal number)", -1);
01149             }
01150             Tcl_SetObjResult(interp, msg);
01151         }
01152     }
01153 
01154     /*
01155      * Free memory.
01156      */
01157 
01158     if (octalSignificandOverflow) {
01159         mp_clear(&octalSignificandBig);
01160     }
01161     if (significandOverflow) {
01162         mp_clear(&significandBig);
01163     }
01164     return status;
01165 }
01166 
01167 /*
01168  *----------------------------------------------------------------------
01169  *
01170  * AccumulateDecimalDigit --
01171  *
01172  *      Consume a decimal digit in a number being scanned.
01173  *
01174  * Results:
01175  *      Returns 1 if the number has overflowed to a bignum, 0 if it still fits
01176  *      in a wide integer.
01177  *
01178  * Side effects:
01179  *      Updates either the wide or bignum representation.
01180  *
01181  *----------------------------------------------------------------------
01182  */
01183 
01184 static int
01185 AccumulateDecimalDigit(
01186     unsigned digit,             /* Digit being scanned. */
01187     int numZeros,               /* Count of zero digits preceding the digit
01188                                  * being scanned. */
01189     Tcl_WideUInt *wideRepPtr,   /* Representation of the partial number as a
01190                                  * wide integer. */
01191     mp_int *bignumRepPtr,       /* Representation of the partial number as a
01192                                  * bignum. */
01193     int bignumFlag)             /* Flag == 1 if the number overflowed previous
01194                                  * to this digit. */
01195 {
01196     int i, n;
01197     Tcl_WideUInt w;
01198 
01199     /*
01200      * Try wide multiplication first
01201      */
01202 
01203     if (!bignumFlag) {
01204         w = *wideRepPtr;
01205         if (w == 0) {
01206             /*
01207              * There's no need to multiply if the multiplicand is zero.
01208              */
01209 
01210             *wideRepPtr = digit;
01211             return 0;
01212         } else if (numZeros >= maxpow10_wide
01213                   || w > ((~(Tcl_WideUInt)0)-digit)/pow10_wide[numZeros+1]) {
01214             /*
01215              * Wide multiplication will overflow.  Expand the
01216              * number to a bignum and fall through into the bignum case.
01217              */
01218 
01219             TclBNInitBignumFromWideUInt (bignumRepPtr, w);
01220         } else {
01221             /*
01222              * Wide multiplication.
01223              */
01224             *wideRepPtr = w * pow10_wide[numZeros+1] + digit;
01225             return 0;
01226         }
01227     }
01228 
01229     /*
01230      * Bignum multiplication.
01231      */
01232 
01233     if (numZeros < log10_DIGIT_MAX) {
01234         /*
01235          * Up to about 8 zeros - single digit multiplication.
01236          */
01237 
01238         mp_mul_d(bignumRepPtr, (mp_digit) pow10_wide[numZeros+1],
01239                 bignumRepPtr);
01240         mp_add_d(bignumRepPtr, (mp_digit) digit, bignumRepPtr);
01241     } else {
01242         /*
01243          * More than single digit multiplication. Multiply by the appropriate
01244          * small powers of 5, and then shift. Large strings of zeroes are
01245          * eaten 256 at a time; this is less efficient than it could be, but
01246          * seems implausible. We presume that DIGIT_BIT is at least 27. The
01247          * first multiplication, by up to 10**7, is done with a one-DIGIT
01248          * multiply (this presumes that DIGIT_BIT >= 24).
01249          */
01250 
01251         n = numZeros + 1;
01252         mp_mul_d(bignumRepPtr, (mp_digit) pow10_wide[n&0x7], bignumRepPtr);
01253         for (i=3; i<=7; ++i) {
01254             if (n & (1 << i)) {
01255                 mp_mul(bignumRepPtr, pow5+i, bignumRepPtr);
01256             }
01257         }
01258         while (n >= 256) {
01259             mp_mul(bignumRepPtr, pow5+8, bignumRepPtr);
01260             n -= 256;
01261         }
01262         mp_mul_2d(bignumRepPtr, (int)(numZeros+1)&~0x7, bignumRepPtr);
01263         mp_add_d(bignumRepPtr, (mp_digit) digit, bignumRepPtr);
01264     }
01265 
01266     return 1;
01267 }
01268 
01269 /*
01270  *----------------------------------------------------------------------
01271  *
01272  * MakeLowPrecisionDouble --
01273  *
01274  *      Makes the double precision number, signum*significand*10**exponent.
01275  *
01276  * Results:
01277  *      Returns the constructed number.
01278  *
01279  *      Common cases, where there are few enough digits that the number can be
01280  *      represented with at most roundoff, are handled specially here. If the
01281  *      number requires more than one rounded operation to compute, the code
01282  *      promotes the significand to a bignum and calls MakeHighPrecisionDouble
01283  *      to do it instead.
01284  *
01285  *----------------------------------------------------------------------
01286  */
01287 
01288 static double
01289 MakeLowPrecisionDouble(
01290     int signum,                 /* 1 if the number is negative, 0 otherwise */
01291     Tcl_WideUInt significand,   /* Significand of the number */
01292     int numSigDigs,             /* Number of digits in the significand */
01293     int exponent)               /* Power of ten */
01294 {
01295     double retval;              /* Value of the number */
01296     mp_int significandBig;      /* Significand expressed as a bignum */
01297 
01298     /*
01299      * With gcc on x86, the floating point rounding mode is double-extended.
01300      * This causes the result of double-precision calculations to be rounded
01301      * twice: once to the precision of double-extended and then again to the
01302      * precision of double. Double-rounding introduces gratuitous errors of 1
01303      * ulp, so we need to change rounding mode to 53-bits.
01304      */
01305 
01306 #if defined(__GNUC__) && defined(__i386)
01307     fpu_control_t roundTo53Bits = 0x027f;
01308     fpu_control_t oldRoundingMode;
01309     _FPU_GETCW(oldRoundingMode);
01310     _FPU_SETCW(roundTo53Bits);
01311 #endif
01312 
01313     /*
01314      * Test for the easy cases.
01315      */
01316 
01317     if (numSigDigs <= DBL_DIG) {
01318         if (exponent >= 0) {
01319             if (exponent <= mmaxpow) {
01320                 /*
01321                  * The significand is an exact integer, and so is
01322                  * 10**exponent. The product will be correct to within 1/2 ulp
01323                  * without special handling.
01324                  */
01325 
01326                 retval = (double)(Tcl_WideInt)significand * pow10[ exponent ];
01327                 goto returnValue;
01328             } else {
01329                 int diff = DBL_DIG - numSigDigs;
01330                 if (exponent-diff <= mmaxpow) {
01331                     /*
01332                      * 10**exponent is not an exact integer, but
01333                      * 10**(exponent-diff) is exact, and so is
01334                      * significand*10**diff, so we can still compute the value
01335                      * with only one roundoff.
01336                      */
01337 
01338                     volatile double factor =
01339                             (double)(Tcl_WideInt)significand * pow10[diff];
01340                     retval = factor * pow10[exponent-diff];
01341                     goto returnValue;
01342                 }
01343             }
01344         } else {
01345             if (exponent >= -mmaxpow) {
01346                 /*
01347                  * 10**-exponent is an exact integer, and so is the
01348                  * significand. Compute the result by one division, again with
01349                  * only one rounding.
01350                  */
01351 
01352                 retval = (double)(Tcl_WideInt)significand / pow10[-exponent];
01353                 goto returnValue;
01354             }
01355         }
01356     }
01357 
01358     /*
01359      * All the easy cases have failed. Promote ths significand to bignum and
01360      * call MakeHighPrecisionDouble to do it the hard way.
01361      */
01362 
01363     TclBNInitBignumFromWideUInt(&significandBig, significand);
01364     retval = MakeHighPrecisionDouble(0, &significandBig, numSigDigs,
01365             exponent);
01366     mp_clear(&significandBig);
01367 
01368     /*
01369      * Come here to return the computed value.
01370      */
01371 
01372   returnValue:
01373     if (signum) {
01374         retval = -retval;
01375     }
01376 
01377     /*
01378      * On gcc on x86, restore the floating point mode word.
01379      */
01380 
01381 #if defined(__GNUC__) && defined(__i386)
01382     _FPU_SETCW(oldRoundingMode);
01383 #endif
01384 
01385     return retval;
01386 }
01387 
01388 /*
01389  *----------------------------------------------------------------------
01390  *
01391  * MakeHighPrecisionDouble --
01392  *
01393  *      Makes the double precision number, signum*significand*10**exponent.
01394  *
01395  * Results:
01396  *      Returns the constructed number.
01397  *
01398  *      MakeHighPrecisionDouble is used when arbitrary-precision arithmetic is
01399  *      needed to ensure correct rounding. It begins by calculating a
01400  *      low-precision approximation to the desired number, and then refines
01401  *      the answer in high precision.
01402  *
01403  *----------------------------------------------------------------------
01404  */
01405 
01406 static double
01407 MakeHighPrecisionDouble(
01408     int signum,                 /* 1=negative, 0=nonnegative */
01409     mp_int *significand,        /* Exact significand of the number */
01410     int numSigDigs,             /* Number of significant digits */
01411     int exponent)               /* Power of 10 by which to multiply */
01412 {
01413     double retval;
01414     int machexp;                /* Machine exponent of a power of 10 */
01415 
01416     /*
01417      * With gcc on x86, the floating point rounding mode is double-extended.
01418      * This causes the result of double-precision calculations to be rounded
01419      * twice: once to the precision of double-extended and then again to the
01420      * precision of double. Double-rounding introduces gratuitous errors of 1
01421      * ulp, so we need to change rounding mode to 53-bits.
01422      */
01423 
01424 #if defined(__GNUC__) && defined(__i386)
01425     fpu_control_t roundTo53Bits = 0x027f;
01426     fpu_control_t oldRoundingMode;
01427     _FPU_GETCW(oldRoundingMode);
01428     _FPU_SETCW(roundTo53Bits);
01429 #endif
01430 
01431     /*
01432      * Quick checks for over/underflow.
01433      */
01434 
01435     if (numSigDigs+exponent-1 > maxDigits) {
01436         retval = HUGE_VAL;
01437         goto returnValue;
01438     }
01439     if (numSigDigs+exponent-1 < minDigits) {
01440         retval = 0;
01441         goto returnValue;
01442     }
01443 
01444     /*
01445      * Develop a first approximation to the significand. It is tempting simply
01446      * to force bignum to double, but that will overflow on input numbers like
01447      * 1.[string repeat 0 1000]1; while this is a not terribly likely
01448      * scenario, we still have to deal with it. Use fraction and exponent
01449      * instead. Once we have the significand, multiply by 10**exponent. Test
01450      * for overflow. Convert back to a double, and test for underflow.
01451      */
01452 
01453     retval = BignumToBiasedFrExp(significand, &machexp);
01454     retval = Pow10TimesFrExp(exponent, retval, &machexp);
01455     if (machexp > DBL_MAX_EXP*log2FLT_RADIX) {
01456         retval = HUGE_VAL;
01457         goto returnValue;
01458     }
01459     retval = SafeLdExp(retval, machexp);
01460     if (retval < tiny) {
01461         retval = tiny;
01462     }
01463 
01464     /*
01465      * Refine the result twice. (The second refinement should be necessary
01466      * only if the best approximation is a power of 2 minus 1/2 ulp).
01467      */
01468 
01469     retval = RefineApproximation(retval, significand, exponent);
01470     retval = RefineApproximation(retval, significand, exponent);
01471 
01472     /*
01473      * Come here to return the computed value.
01474      */
01475 
01476   returnValue:
01477     if (signum) {
01478         retval = -retval;
01479     }
01480 
01481     /*
01482      * On gcc on x86, restore the floating point mode word.
01483      */
01484 
01485 #if defined(__GNUC__) && defined(__i386)
01486     _FPU_SETCW(oldRoundingMode);
01487 #endif
01488     return retval;
01489 }
01490 
01491 /*
01492  *----------------------------------------------------------------------
01493  *
01494  * MakeNaN --
01495  *
01496  *      Makes a "Not a Number" given a set of bits to put in the tag bits
01497  *
01498  *      Note that a signalling NaN is never returned.
01499  *
01500  *----------------------------------------------------------------------
01501  */
01502 
01503 #ifdef IEEE_FLOATING_POINT
01504 static double
01505 MakeNaN(
01506     int signum,                 /* Sign bit (1=negative, 0=nonnegative */
01507     Tcl_WideUInt tags)          /* Tag bits to put in the NaN */
01508 {
01509     union {
01510         Tcl_WideUInt iv;
01511         double dv;
01512     } theNaN;
01513 
01514     theNaN.iv = tags;
01515     theNaN.iv &= (((Tcl_WideUInt) 1) << 51) - 1;
01516     if (signum) {
01517         theNaN.iv |= ((Tcl_WideUInt) (0x8000 | NAN_START)) << 48;
01518     } else {
01519         theNaN.iv |= ((Tcl_WideUInt) NAN_START) << 48;
01520     }
01521     if (n770_fp) {
01522         theNaN.iv = Nokia770Twiddle(theNaN.iv);
01523     }
01524     return theNaN.dv;
01525 }
01526 #endif
01527 
01528 /*
01529  *----------------------------------------------------------------------
01530  *
01531  * RefineApproximation --
01532  *
01533  *      Given a poor approximation to a floating point number, returns a
01534  *      better one. (The better approximation is correct to within 1 ulp, and
01535  *      is entirely correct if the poor approximation is correct to 1 ulp.)
01536  *
01537  * Results:
01538  *      Returns the improved result.
01539  *
01540  *----------------------------------------------------------------------
01541  */
01542 
01543 static double
01544 RefineApproximation(
01545     double approxResult,        /* Approximate result of conversion */
01546     mp_int *exactSignificand,   /* Integer significand */
01547     int exponent)               /* Power of 10 to multiply by significand */
01548 {
01549     int M2, M5;                 /* Powers of 2 and of 5 needed to put the
01550                                  * decimal and binary numbers over a common
01551                                  * denominator. */
01552     double significand;         /* Sigificand of the binary number */
01553     int binExponent;            /* Exponent of the binary number */
01554     int msb;                    /* Most significant bit position of an
01555                                  * intermediate result */
01556     int nDigits;                /* Number of mp_digit's in an intermediate
01557                                  * result */
01558     mp_int twoMv;               /* Approx binary value expressed as an exact
01559                                  * integer scaled by the multiplier 2M */
01560     mp_int twoMd;               /* Exact decimal value expressed as an exact
01561                                  * integer scaled by the multiplier 2M */
01562     int scale;                  /* Scale factor for M */
01563     int multiplier;             /* Power of two to scale M */
01564     double num, den;            /* Numerator and denominator of the correction
01565                                  * term */
01566     double quot;                /* Correction term */
01567     double minincr;             /* Lower bound on the absolute value of the
01568                                  * correction term. */
01569     int i;
01570 
01571     /*
01572      * The first approximation is always low. If we find that it's HUGE_VAL,
01573      * we're done.
01574      */
01575 
01576     if (approxResult == HUGE_VAL) {
01577         return approxResult;
01578     }
01579 
01580     /*
01581      * Find a common denominator for the decimal and binary fractions. The
01582      * common denominator will be 2**M2 + 5**M5.
01583      */
01584 
01585     significand = frexp(approxResult, &binExponent);
01586     i = mantBits - binExponent;
01587     if (i < 0) {
01588         M2 = 0;
01589     } else {
01590         M2 = i;
01591     }
01592     if (exponent > 0) {
01593         M5 = 0;
01594     } else {
01595         M5 = -exponent;
01596         if ((M5-1) > M2) {
01597             M2 = M5-1;
01598         }
01599     }
01600 
01601     /*
01602      * The floating point number is significand*2**binExponent. Compute the
01603      * large integer significand*2**(binExponent+M2+1). The 2**-1 bit of the
01604      * significand (the most significant) corresponds to the
01605      * 2**(binExponent+M2 + 1) bit of 2*M2*v. Allocate enough digits to hold
01606      * that quantity, then convert the significand to a large integer, scaled
01607      * appropriately. Then multiply by the appropriate power of 5.
01608      */
01609 
01610     msb = binExponent + M2;     /* 1008 */
01611     nDigits = msb / DIGIT_BIT + 1;
01612     mp_init_size(&twoMv, nDigits);
01613     i = (msb % DIGIT_BIT + 1);
01614     twoMv.used = nDigits;
01615     significand *= SafeLdExp(1.0, i);
01616     while (--nDigits >= 0) {
01617         twoMv.dp[nDigits] = (mp_digit) significand;
01618         significand -= (mp_digit) significand;
01619         significand = SafeLdExp(significand, DIGIT_BIT);
01620     }
01621     for (i = 0; i <= 8; ++i) {
01622         if (M5 & (1 << i)) {
01623             mp_mul(&twoMv, pow5+i, &twoMv);
01624         }
01625     }
01626 
01627     /*
01628      * Collect the decimal significand as a high precision integer. The least
01629      * significant bit corresponds to bit M2+exponent+1 so it will need to be
01630      * shifted left by that many bits after being multiplied by
01631      * 5**(M5+exponent).
01632      */
01633 
01634     mp_init_copy(&twoMd, exactSignificand);
01635     for (i=0; i<=8; ++i) {
01636         if ((M5+exponent) & (1 << i)) {
01637             mp_mul(&twoMd, pow5+i, &twoMd);
01638         }
01639     }
01640     mp_mul_2d(&twoMd, M2+exponent+1, &twoMd);
01641     mp_sub(&twoMd, &twoMv, &twoMd);
01642 
01643     /*
01644      * The result, 2Mv-2Md, needs to be divided by 2M to yield a correction
01645      * term. Because 2M may well overflow a double, we need to scale the
01646      * denominator by a factor of 2**binExponent-mantBits
01647      */
01648 
01649     scale = binExponent - mantBits - 1;
01650 
01651     mp_set(&twoMv, 1);
01652     for (i=0; i<=8; ++i) {
01653         if (M5 & (1 << i)) {
01654             mp_mul(&twoMv, pow5+i, &twoMv);
01655         }
01656     }
01657     multiplier = M2 + scale + 1;
01658     if (multiplier > 0) {
01659         mp_mul_2d(&twoMv, multiplier, &twoMv);
01660     } else if (multiplier < 0) {
01661         mp_div_2d(&twoMv, -multiplier, &twoMv, NULL);
01662     }
01663 
01664     /*
01665      * If the result is less than unity, the error is less than 1/2 unit in
01666      * the last place, so there's no correction to make.
01667      */
01668 
01669     if (mp_cmp_mag(&twoMd, &twoMv) == MP_LT) {
01670         mp_clear(&twoMd);
01671         mp_clear(&twoMv);
01672         return approxResult;
01673     }
01674 
01675     /*
01676      * Convert the numerator and denominator of the corrector term accurately
01677      * to floating point numbers.
01678      */
01679 
01680     num = TclBignumToDouble(&twoMd);
01681     den = TclBignumToDouble(&twoMv);
01682 
01683     quot = SafeLdExp(num/den, scale);
01684     minincr = SafeLdExp(1.0, binExponent-mantBits);
01685 
01686     if (quot<0. && quot>-minincr) {
01687         quot = -minincr;
01688     } else if (quot>0. && quot<minincr) {
01689         quot = minincr;
01690     }
01691 
01692     mp_clear(&twoMd);
01693     mp_clear(&twoMv);
01694 
01695     return approxResult + quot;
01696 }
01697 
01698 /*
01699  *----------------------------------------------------------------------
01700  *
01701  * TclDoubleDigits --
01702  *
01703  *      Converts a double to a string of digits.
01704  *
01705  * Results:
01706  *      Returns the position of the character in the string after which the
01707  *      decimal point should appear. Since the string contains only
01708  *      significant digits, the position may be less than zero or greater than
01709  *      the length of the string.
01710  *
01711  * Side effects:
01712  *      Stores the digits in the given buffer and sets 'signum' according to
01713  *      the sign of the number.
01714  *
01715  *----------------------------------------------------------------------
01716 
01717  */
01718 
01719 int
01720 TclDoubleDigits(
01721     char *buffer,               /* Buffer in which to store the result, must
01722                                  * have at least 18 chars */
01723     double v,                   /* Number to convert. Must be finite, and not
01724                                  * NaN */
01725     int *signum)                /* Output: 1 if the number is negative.
01726                                  * Should handle -0 correctly on the IEEE
01727                                  * architecture. */
01728 {
01729     int e;                      /* Power of FLT_RADIX that satisfies
01730                                  * v = f * FLT_RADIX**e */
01731     int lowOK, highOK;
01732     mp_int r;                   /* Scaled significand. */
01733     mp_int s;                   /* Divisor such that v = r / s */
01734     int smallestSig;            /* Flag == 1 iff v's significand is the
01735                                  * smallest that can be represented. */
01736     mp_int mplus;               /* Scaled epsilon: (r + 2* mplus) == v(+)
01737                                  * where v(+) is the floating point successor
01738                                  * of v. */
01739     mp_int mminus;              /* Scaled epsilon: (r - 2*mminus) == v(-)
01740                                  * where v(-) is the floating point
01741                                  * predecessor of v. */
01742     mp_int temp;
01743     int rfac2 = 0;              /* Powers of 2 and 5 by which large */
01744     int rfac5 = 0;              /* integers should be scaled.       */
01745     int sfac2 = 0;
01746     int sfac5 = 0;
01747     int mplusfac2 = 0;
01748     int mminusfac2 = 0;
01749     char c;
01750     int i, k, n;
01751 
01752     /*
01753      * Split the number into absolute value and signum.
01754      */
01755 
01756     v = AbsoluteValue(v, signum);
01757 
01758     /*
01759      * Handle zero specially.
01760      */
01761 
01762     if (v == 0.0) {
01763         *buffer++ = '0';
01764         *buffer++ = '\0';
01765         return 1;
01766     }
01767 
01768     /*
01769      * Find a large integer r, and integer e, such that
01770      *         v = r * FLT_RADIX**e
01771      * and r is as small as possible. Also determine whether the significand
01772      * is the smallest possible.
01773      */
01774 
01775     smallestSig = GetIntegerTimesPower(v, &r, &e);
01776 
01777     lowOK = highOK = (mp_iseven(&r));
01778 
01779     /*
01780      * We are going to want to develop integers r, s, mplus, and mminus such
01781      * that v = r / s, v(+)-v / 2 = mplus / s; v-v(-) / 2 = mminus / s and
01782      * then scale either s or r, mplus, mminus by an appropriate power of ten.
01783      *
01784      * We actually do this by keeping track of the powers of 2 and 5 by which
01785      * f is multiplied to yield v and by which 1 is multiplied to yield s,
01786      * mplus, and mminus.
01787      */
01788 
01789     if (e >= 0) {
01790         int bits = e * log2FLT_RADIX;
01791 
01792         if (!smallestSig) {
01793             /*
01794              * Normal case, m+ and m- are both FLT_RADIX**e
01795              */
01796 
01797             rfac2 = bits + 1;
01798             sfac2 = 1;
01799             mplusfac2 = bits;
01800             mminusfac2 = bits;
01801         } else {
01802             /*
01803              * If f is equal to the smallest significand, then we need another
01804              * factor of FLT_RADIX in s to cope with stepping to the next
01805              * smaller exponent when going to e's predecessor.
01806              */
01807 
01808             rfac2 = bits + log2FLT_RADIX + 1;
01809             sfac2 = 1 + log2FLT_RADIX;
01810             mplusfac2 = bits + log2FLT_RADIX;
01811             mminusfac2 = bits;
01812         }
01813     } else {
01814         /*
01815          * v has digits after the binary point
01816          */
01817 
01818         if (e <= DBL_MIN_EXP-DBL_MANT_DIG || !smallestSig) {
01819             /*
01820              * Either f isn't the smallest significand or e is the smallest
01821              * exponent. mplus and mminus will both be 1.
01822              */
01823 
01824             rfac2 = 1;
01825             sfac2 = 1 - e * log2FLT_RADIX;
01826             mplusfac2 = 0;
01827             mminusfac2 = 0;
01828         } else {
01829             /*
01830              * f is the smallest significand, but e is not the smallest
01831              * exponent. We need to scale by FLT_RADIX again to cope with the
01832              * fact that v's predecessor has a smaller exponent.
01833              */
01834 
01835             rfac2 = 1 + log2FLT_RADIX;
01836             sfac2 = 1 + log2FLT_RADIX * (1 - e);
01837             mplusfac2 = FLT_RADIX;
01838             mminusfac2 = 0;
01839         }
01840     }
01841 
01842     /*
01843      * Estimate the highest power of ten that will be needed to hold the
01844      * result.
01845      */
01846 
01847     k = (int) ceil(log(v) / log(10.));
01848     if (k >= 0) {
01849         sfac2 += k;
01850         sfac5 = k;
01851     } else {
01852         rfac2 -= k;
01853         mplusfac2 -= k;
01854         mminusfac2 -= k;
01855         rfac5 = -k;
01856     }
01857 
01858     /*
01859      * Scale r, s, mplus, mminus by the appropriate powers of 2 and 5.
01860      */
01861 
01862     mp_init_set(&mplus, 1);
01863     for (i=0 ; i<=8 ; ++i) {
01864         if (rfac5 & (1 << i)) {
01865             mp_mul(&mplus, pow5+i, &mplus);
01866         }
01867     }
01868     mp_mul(&r, &mplus, &r);
01869     mp_mul_2d(&r, rfac2, &r);
01870     mp_init_copy(&mminus, &mplus);
01871     mp_mul_2d(&mplus, mplusfac2, &mplus);
01872     mp_mul_2d(&mminus, mminusfac2, &mminus);
01873     mp_init_set(&s, 1);
01874     for (i=0 ; i<=8 ; ++i) {
01875         if (sfac5 & (1 << i)) {
01876             mp_mul(&s, pow5+i, &s);
01877         }
01878     }
01879     mp_mul_2d(&s, sfac2, &s);
01880 
01881     /*
01882      * It is possible for k to be off by one because we used an inexact
01883      * logarithm.
01884      */
01885 
01886     mp_init(&temp);
01887     mp_add(&r, &mplus, &temp);
01888     i = mp_cmp_mag(&temp, &s);
01889     if (i>0 || (highOK && i==0)) {
01890         mp_mul_d(&s, 10, &s);
01891         ++k;
01892     } else {
01893         mp_mul_d(&temp, 10, &temp);
01894         i = mp_cmp_mag(&temp, &s);
01895         if (i<0 || (highOK && i==0)) {
01896             mp_mul_d(&r, 10, &r);
01897             mp_mul_d(&mplus, 10, &mplus);
01898             mp_mul_d(&mminus, 10, &mminus);
01899             --k;
01900         }
01901     }
01902 
01903     /*
01904      * At this point, k contains the power of ten by which we're scaling the
01905      * result. r/s is at least 1/10 and strictly less than ten, and v = r/s *
01906      * 10**k. mplus and mminus give the rounding limits.
01907      */
01908 
01909     for (;;) {
01910         int tc1, tc2;
01911 
01912         mp_mul_d(&r, 10, &r);
01913         mp_div(&r, &s, &temp, &r);      /* temp = 10r / s; r = 10r mod s */
01914         i = temp.dp[0];
01915         mp_mul_d(&mplus, 10, &mplus);
01916         mp_mul_d(&mminus, 10, &mminus);
01917         tc1 = mp_cmp_mag(&r, &mminus);
01918         if (lowOK) {
01919             tc1 = (tc1 <= 0);
01920         } else {
01921             tc1 = (tc1 < 0);
01922         }
01923         mp_add(&r, &mplus, &temp);
01924         tc2 = mp_cmp_mag(&temp, &s);
01925         if (highOK) {
01926             tc2 = (tc2 >= 0);
01927         } else {
01928             tc2= (tc2 > 0);
01929         }
01930         if (!tc1) {
01931             if (!tc2) {
01932                 *buffer++ = '0' + i;
01933             } else {
01934                 c = (char) (i + '1');
01935                 break;
01936             }
01937         } else {
01938             if (!tc2) {
01939                 c = (char) (i + '0');
01940             } else {
01941                 mp_mul_2d(&r, 1, &r);
01942                 n = mp_cmp_mag(&r, &s);
01943                 if (n < 0) {
01944                     c = (char) (i + '0');
01945                 } else {
01946                     c = (char) (i + '1');
01947                 }
01948             }
01949             break;
01950         }
01951     };
01952     *buffer++ = c;
01953     *buffer++ = '\0';
01954 
01955     /*
01956      * Free memory, and return.
01957      */
01958 
01959     mp_clear_multi(&r, &s, &mplus, &mminus, &temp, NULL);
01960     return k;
01961 }
01962 
01963 /*
01964  *----------------------------------------------------------------------
01965  *
01966  * AbsoluteValue --
01967  *
01968  *      Splits a 'double' into its absolute value and sign.
01969  *
01970  * Results:
01971  *      Returns the absolute value.
01972  *
01973  * Side effects:
01974  *      Stores the signum in '*signum'.
01975  *
01976  *----------------------------------------------------------------------
01977  */
01978 
01979 static double
01980 AbsoluteValue(
01981     double v,                   /* Number to split */
01982     int *signum)                /* (Output) Sign of the number 1=-, 0=+ */
01983 {
01984     /*
01985      * Take the absolute value of the number, and report the number's sign.
01986      * Take special steps to preserve signed zeroes in IEEE floating point.
01987      * (We can't use fpclassify, because that's a C9x feature and we still
01988      * have to build on C89 compilers.)
01989      */
01990 
01991 #ifndef IEEE_FLOATING_POINT
01992     if (v >= 0.0) {
01993         *signum = 0;
01994     } else {
01995         *signum = 1;
01996         v = -v;
01997     }
01998 #else
01999     union {
02000         Tcl_WideUInt iv;
02001         double dv;
02002     } bitwhack;
02003     bitwhack.dv = v;
02004     if (n770_fp) {
02005         bitwhack.iv = Nokia770Twiddle(bitwhack.iv);
02006     }
02007     if (bitwhack.iv & ((Tcl_WideUInt) 1 << 63)) {
02008         *signum = 1;
02009         bitwhack.iv &= ~((Tcl_WideUInt) 1 << 63);
02010         if (n770_fp) {
02011             bitwhack.iv = Nokia770Twiddle(bitwhack.iv);
02012         }
02013         v = bitwhack.dv;
02014     } else {
02015         *signum = 0;
02016     }
02017 #endif
02018     return v;
02019 }
02020 
02021 /*
02022  *----------------------------------------------------------------------
02023  *
02024  * GetIntegerTimesPower --
02025  *
02026  *      Converts a floating point number to an exact integer times a power of
02027  *      the floating point radix.
02028  *
02029  * Results:
02030  *      Returns 1 if it converted the smallest significand, 0 otherwise.
02031  *
02032  * Side effects:
02033  *      Initializes the integer value (does not just assign it), and stores
02034  *      the exponent.
02035  *
02036  *----------------------------------------------------------------------
02037  */
02038 
02039 static int
02040 GetIntegerTimesPower(
02041     double v,                   /* Value to convert */
02042     mp_int *rPtr,               /* (Output) Integer value */
02043     int *ePtr)                  /* (Output) Power of FLT_RADIX by which r must
02044                                  * be multiplied to yield v*/
02045 {
02046     double a, f;
02047     int e, i, n;
02048 
02049     /*
02050      * Develop f and e such that v = f * FLT_RADIX**e, with
02051      * 1.0/FLT_RADIX <= f < 1.
02052      */
02053 
02054     f = frexp(v, &e);
02055 #if FLT_RADIX > 2
02056     n = e % log2FLT_RADIX;
02057     if (n > 0) {
02058         n -= log2FLT_RADIX;
02059         e += 1;
02060         f *= ldexp(1.0, n);
02061     }
02062     e = (e - n) / log2FLT_RADIX;
02063 #endif
02064     if (f == 1.0) {
02065         f = 1.0 / FLT_RADIX;
02066         e += 1;
02067     }
02068 
02069     /*
02070      * If the original number was denormalized, adjust e and f to be denormal
02071      * as well.
02072      */
02073 
02074     if (e < DBL_MIN_EXP) {
02075         n = mantBits + (e - DBL_MIN_EXP)*log2FLT_RADIX;
02076         f = ldexp(f, (e - DBL_MIN_EXP)*log2FLT_RADIX);
02077         e = DBL_MIN_EXP;
02078         n = (n + DIGIT_BIT - 1) / DIGIT_BIT;
02079     } else {
02080         n = mantDIGIT;
02081     }
02082 
02083     /*
02084      * Now extract the base-2**DIGIT_BIT digits of f into a multi-precision
02085      * integer r. Preserve the invariant v = r * 2**rfac2 * FLT_RADIX**e by
02086      * adjusting e.
02087      */
02088 
02089     a = f;
02090     n = mantDIGIT;
02091     mp_init_size(rPtr, n);
02092     rPtr->used = n;
02093     rPtr->sign = MP_ZPOS;
02094     i = (mantBits % DIGIT_BIT);
02095     if (i == 0) {
02096         i = DIGIT_BIT;
02097     }
02098     while (n > 0) {
02099         a *= ldexp(1.0, i);
02100         i = DIGIT_BIT;
02101         rPtr->dp[--n] = (mp_digit) a;
02102         a -= (mp_digit) a;
02103     }
02104     *ePtr = e - DBL_MANT_DIG;
02105     return (f == 1.0 / FLT_RADIX);
02106 }
02107 
02108 /*
02109  *----------------------------------------------------------------------
02110  *
02111  * TclInitDoubleConversion --
02112  *
02113  *      Initializes constants that are needed for conversions to and from
02114  *      'double'
02115  *
02116  * Results:
02117  *      None.
02118  *
02119  * Side effects:
02120  *      The log base 2 of the floating point radix, the number of bits in a
02121  *      double mantissa, and a table of the powers of five and ten are
02122  *      computed and stored.
02123  *
02124  *----------------------------------------------------------------------
02125  */
02126 
02127 void
02128 TclInitDoubleConversion(void)
02129 {
02130     int i;
02131     int x;
02132     Tcl_WideUInt u;
02133     double d;
02134 
02135 #ifdef IEEE_FLOATING_POINT
02136     union {
02137         double dv;
02138         Tcl_WideUInt iv;
02139     } bitwhack;
02140 #endif
02141 
02142     /*
02143      * Initialize table of powers of 10 expressed as wide integers.
02144      */
02145 
02146     maxpow10_wide = (int)
02147             floor(sizeof(Tcl_WideUInt) * CHAR_BIT * log(2.) / log(10.));
02148     pow10_wide = (Tcl_WideUInt *)
02149             ckalloc((maxpow10_wide + 1) * sizeof(Tcl_WideUInt));
02150     u = 1;
02151     for (i = 0; i < maxpow10_wide; ++i) {
02152         pow10_wide[i] = u;
02153         u *= 10;
02154     }
02155     pow10_wide[i] = u;
02156 
02157     /*
02158      * Determine how many bits of precision a double has, and how many
02159      * decimal digits that represents.
02160      */
02161 
02162     if (frexp((double) FLT_RADIX, &log2FLT_RADIX) != 0.5) {
02163         Tcl_Panic("This code doesn't work on a decimal machine!");
02164     }
02165     --log2FLT_RADIX;
02166     mantBits = DBL_MANT_DIG * log2FLT_RADIX;
02167     d = 1.0;
02168 
02169     /*
02170      * Initialize a table of powers of ten that can be exactly represented
02171      * in a double.
02172      */
02173 
02174     x = (int) (DBL_MANT_DIG * log((double) FLT_RADIX) / log(5.0));
02175     if (x < MAXPOW) {
02176         mmaxpow = x;
02177     } else {
02178         mmaxpow = MAXPOW;
02179     }
02180     for (i=0 ; i<=mmaxpow ; ++i) {
02181         pow10[i] = d;
02182         d *= 10.0;
02183     }
02184 
02185     /*
02186      * Initialize a table of large powers of five.
02187      */
02188 
02189     for (i=0; i<9; ++i) {
02190         mp_init(pow5 + i);
02191     }
02192     mp_set(pow5, 5);
02193     for (i=0; i<8; ++i) {
02194         mp_sqr(pow5+i, pow5+i+1);
02195     }
02196 
02197     /*
02198      * Determine the number of decimal digits to the left and right of the
02199      * decimal point in the largest and smallest double, the smallest double
02200      * that differs from zero, and the number of mp_digits needed to represent
02201      * the significand of a double.
02202      */
02203 
02204     tiny = SafeLdExp(1.0, DBL_MIN_EXP * log2FLT_RADIX - mantBits);
02205     maxDigits = (int) ((DBL_MAX_EXP * log((double) FLT_RADIX)
02206             + 0.5 * log(10.)) / log(10.));
02207     minDigits = (int) floor((DBL_MIN_EXP - DBL_MANT_DIG)
02208             * log((double) FLT_RADIX) / log(10.));
02209     mantDIGIT = (mantBits + DIGIT_BIT-1) / DIGIT_BIT;
02210     log10_DIGIT_MAX = (int) floor(DIGIT_BIT * log(2.) / log(10.));
02211 
02212     /*
02213      * Nokia 770's software-emulated floating point is "middle endian": the
02214      * bytes within a 32-bit word are little-endian (like the native
02215      * integers), but the two words of a 'double' are presented most
02216      * significant word first.
02217      */
02218 
02219 #ifdef IEEE_FLOATING_POINT
02220     bitwhack.dv = 1.000000238418579;
02221                                 /* 3ff0 0000 4000 0000 */
02222     if ((bitwhack.iv >> 32) == 0x3ff00000) {
02223         n770_fp = 0;
02224     } else if ((bitwhack.iv & 0xffffffff) == 0x3ff00000) {
02225         n770_fp = 1;
02226     } else {
02227         Tcl_Panic("unknown floating point word order on this machine");
02228     }
02229 #endif
02230 }
02231 
02232 /*
02233  *----------------------------------------------------------------------
02234  *
02235  * TclFinalizeDoubleConversion --
02236  *
02237  *      Cleans up this file on exit.
02238  *
02239  * Results:
02240  *      None
02241  *
02242  * Side effects:
02243  *      Memory allocated by TclInitDoubleConversion is freed.
02244  *
02245  *----------------------------------------------------------------------
02246  */
02247 
02248 void
02249 TclFinalizeDoubleConversion(void)
02250 {
02251     int i;
02252 
02253     Tcl_Free((char *) pow10_wide);
02254     for (i=0; i<9; ++i) {
02255         mp_clear(pow5 + i);
02256     }
02257 }
02258 
02259 /*
02260  *----------------------------------------------------------------------
02261  *
02262  * Tcl_InitBignumFromDouble --
02263  *
02264  *      Extracts the integer part of a double and converts it to an arbitrary
02265  *      precision integer.
02266  *
02267  * Results:
02268  *      None.
02269  *
02270  * Side effects:
02271  *      Initializes the bignum supplied, and stores the converted number in
02272  *      it.
02273  *
02274  *----------------------------------------------------------------------
02275  */
02276 
02277 int
02278 Tcl_InitBignumFromDouble(
02279     Tcl_Interp *interp,         /* For error message */
02280     double d,                   /* Number to convert */
02281     mp_int *b)                  /* Place to store the result */
02282 {
02283     double fract;
02284     int expt;
02285 
02286     /*
02287      * Infinite values can't convert to bignum.
02288      */
02289 
02290     if (TclIsInfinite(d)) {
02291         if (interp != NULL) {
02292             const char *s = "integer value too large to represent";
02293 
02294             Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1));
02295             Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
02296         }
02297         return TCL_ERROR;
02298     }
02299 
02300     fract = frexp(d,&expt);
02301     if (expt <= 0) {
02302         mp_init(b);
02303         mp_zero(b);
02304     } else {
02305         Tcl_WideInt w = (Tcl_WideInt) ldexp(fract, mantBits);
02306         int shift = expt - mantBits;
02307 
02308         TclBNInitBignumFromWideInt(b, w);
02309         if (shift < 0) {
02310             mp_div_2d(b, -shift, b, NULL);
02311         } else if (shift > 0) {
02312             mp_mul_2d(b, shift, b);
02313         }
02314     }
02315     return TCL_OK;
02316 }
02317 
02318 /*
02319  *----------------------------------------------------------------------
02320  *
02321  * TclBignumToDouble --
02322  *
02323  *      Convert an arbitrary-precision integer to a native floating point
02324  *      number.
02325  *
02326  * Results:
02327  *      Returns the converted number. Sets errno to ERANGE if the number is
02328  *      too large to convert.
02329  *
02330  *----------------------------------------------------------------------
02331  */
02332 
02333 double
02334 TclBignumToDouble(
02335     mp_int *a)                  /* Integer to convert. */
02336 {
02337     mp_int b;
02338     int bits, shift, i;
02339     double r;
02340 
02341     /*
02342      * Determine how many bits we need, and extract that many from the input.
02343      * Round to nearest unit in the last place.
02344      */
02345 
02346     bits = mp_count_bits(a);
02347     if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
02348         errno = ERANGE;
02349         if (a->sign == MP_ZPOS) {
02350             return HUGE_VAL;
02351         } else {
02352             return -HUGE_VAL;
02353         }
02354     }
02355     shift = mantBits + 1 - bits;
02356     mp_init(&b);
02357     if (shift > 0) {
02358         mp_mul_2d(a, shift, &b);
02359     } else if (shift < 0) {
02360         mp_div_2d(a, -shift, &b, NULL);
02361     } else {
02362         mp_copy(a, &b);
02363     }
02364     mp_add_d(&b, 1, &b);
02365     mp_div_2d(&b, 1, &b, NULL);
02366 
02367     /*
02368      * Accumulate the result, one mp_digit at a time.
02369      */
02370 
02371     r = 0.0;
02372     for (i=b.used-1 ; i>=0 ; --i) {
02373         r = ldexp(r, DIGIT_BIT) + b.dp[i];
02374     }
02375     mp_clear(&b);
02376 
02377     /*
02378      * Scale the result to the correct number of bits.
02379      */
02380 
02381     r = ldexp(r, bits - mantBits);
02382 
02383     /*
02384      * Return the result with the appropriate sign.
02385      */
02386 
02387     if (a->sign == MP_ZPOS) {
02388         return r;
02389     } else {
02390         return -r;
02391     }
02392 }
02393 
02394 double
02395 TclCeil(
02396     mp_int *a)                  /* Integer to convert. */
02397 {
02398     double r = 0.0;
02399     mp_int b;
02400 
02401     mp_init(&b);
02402     if (mp_cmp_d(a, 0) == MP_LT) {
02403         mp_neg(a, &b);
02404         r = -TclFloor(&b);
02405     } else {
02406         int bits = mp_count_bits(a);
02407 
02408         if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
02409             r = HUGE_VAL;
02410         } else {
02411             int i, exact = 1, shift = mantBits - bits;
02412 
02413             if (shift > 0) {
02414                 mp_mul_2d(a, shift, &b);
02415             } else if (shift < 0) {
02416                 mp_int d;
02417                 mp_init(&d);
02418                 mp_div_2d(a, -shift, &b, &d);
02419                 exact = mp_iszero(&d);
02420                 mp_clear(&d);
02421             } else {
02422                 mp_copy(a, &b);
02423             }
02424             if (!exact) {
02425                 mp_add_d(&b, 1, &b);
02426             }
02427             for (i=b.used-1 ; i>=0 ; --i) {
02428                 r = ldexp(r, DIGIT_BIT) + b.dp[i];
02429             }
02430             r = ldexp(r, bits - mantBits);
02431         }
02432     }
02433     mp_clear(&b);
02434     return r;
02435 }
02436 
02437 double
02438 TclFloor(
02439     mp_int *a)                  /* Integer to convert. */
02440 {
02441     double r = 0.0;
02442     mp_int b;
02443 
02444     mp_init(&b);
02445     if (mp_cmp_d(a, 0) == MP_LT) {
02446         mp_neg(a, &b);
02447         r = -TclCeil(&b);
02448     } else {
02449         int bits = mp_count_bits(a);
02450 
02451         if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
02452             r = DBL_MAX;
02453         } else {
02454             int i, shift = mantBits - bits;
02455 
02456             if (shift > 0) {
02457                 mp_mul_2d(a, shift, &b);
02458             } else if (shift < 0) {
02459                 mp_div_2d(a, -shift, &b, NULL);
02460             } else {
02461                 mp_copy(a, &b);
02462             }
02463             for (i=b.used-1 ; i>=0 ; --i) {
02464                 r = ldexp(r, DIGIT_BIT) + b.dp[i];
02465             }
02466             r = ldexp(r, bits - mantBits);
02467         }
02468     }
02469     mp_clear(&b);
02470     return r;
02471 }
02472 
02473 /*
02474  *----------------------------------------------------------------------
02475  *
02476  * BignumToBiasedFrExp --
02477  *
02478  *      Convert an arbitrary-precision integer to a native floating point
02479  *      number in the range [0.5,1) times a power of two. NOTE: Intentionally
02480  *      converts to a number that's a few ulp too small, so that
02481  *      RefineApproximation will not overflow near the high end of the
02482  *      machine's arithmetic range.
02483  *
02484  * Results:
02485  *      Returns the converted number.
02486  *
02487  * Side effects:
02488  *      Stores the exponent of two in 'machexp'.
02489  *
02490  *----------------------------------------------------------------------
02491  */
02492 
02493 static double
02494 BignumToBiasedFrExp(
02495     mp_int *a,                  /* Integer to convert */
02496     int *machexp)               /* Power of two */
02497 {
02498     mp_int b;
02499     int bits;
02500     int shift;
02501     int i;
02502     double r;
02503 
02504     /*
02505      * Determine how many bits we need, and extract that many from the input.
02506      * Round to nearest unit in the last place.
02507      */
02508 
02509     bits = mp_count_bits(a);
02510     shift = mantBits - 2 - bits;
02511     mp_init(&b);
02512     if (shift > 0) {
02513         mp_mul_2d(a, shift, &b);
02514     } else if (shift < 0) {
02515         mp_div_2d(a, -shift, &b, NULL);
02516     } else {
02517         mp_copy(a, &b);
02518     }
02519 
02520     /*
02521      * Accumulate the result, one mp_digit at a time.
02522      */
02523 
02524     r = 0.0;
02525     for (i=b.used-1; i>=0; --i) {
02526         r = ldexp(r, DIGIT_BIT) + b.dp[i];
02527     }
02528     mp_clear(&b);
02529 
02530     /*
02531      * Return the result with the appropriate sign.
02532      */
02533 
02534     *machexp = bits - mantBits + 2;
02535     return ((a->sign == MP_ZPOS) ? r : -r);
02536 }
02537 
02538 /*
02539  *----------------------------------------------------------------------
02540  *
02541  * Pow10TimesFrExp --
02542  *
02543  *      Multiply a power of ten by a number expressed as fraction and
02544  *      exponent.
02545  *
02546  * Results:
02547  *      Returns the significand of the result.
02548  *
02549  * Side effects:
02550  *      Overwrites the 'machexp' parameter with the exponent of the result.
02551  *
02552  * Assumes that 'exponent' is such that 10**exponent would be a double, even
02553  * though 'fraction*10**(machexp+exponent)' might overflow.
02554  *
02555  *----------------------------------------------------------------------
02556  */
02557 
02558 static double
02559 Pow10TimesFrExp(
02560     int exponent,               /* Power of 10 to multiply by */
02561     double fraction,            /* Significand of multiplicand */
02562     int *machexp)               /* On input, exponent of multiplicand. On
02563                                  * output, exponent of result. */
02564 {
02565     int i, j;
02566     int expt = *machexp;
02567     double retval = fraction;
02568 
02569     if (exponent > 0) {
02570         /*
02571          * Multiply by 10**exponent
02572          */
02573 
02574         retval = frexp(retval * pow10[exponent&0xf], &j);
02575         expt += j;
02576         for (i=4; i<9; ++i) {
02577             if (exponent & (1<<i)) {
02578                 retval = frexp(retval * pow_10_2_n[i], &j);
02579                 expt += j;
02580             }
02581         }
02582     } else if (exponent < 0) {
02583         /*
02584          * Divide by 10**-exponent
02585          */
02586 
02587         retval = frexp(retval / pow10[(-exponent) & 0xf], &j);
02588         expt += j;
02589         for (i=4; i<9; ++i) {
02590             if ((-exponent) & (1<<i)) {
02591                 retval = frexp(retval / pow_10_2_n[i], &j);
02592                 expt += j;
02593             }
02594         }
02595     }
02596 
02597     *machexp = expt;
02598     return retval;
02599 }
02600 
02601 /*
02602  *----------------------------------------------------------------------
02603  *
02604  * SafeLdExp --
02605  *
02606  *      Do an 'ldexp' operation, but handle denormals gracefully.
02607  *
02608  * Results:
02609  *      Returns the appropriately scaled value.
02610  *
02611  *      On some platforms, 'ldexp' fails when presented with a number too
02612  *      small to represent as a normalized double. This routine does 'ldexp'
02613  *      in two steps for those numbers, to return correctly denormalized
02614  *      values.
02615  *
02616  *----------------------------------------------------------------------
02617  */
02618 
02619 static double
02620 SafeLdExp(
02621     double fract,
02622     int expt)
02623 {
02624     int minexpt = DBL_MIN_EXP * log2FLT_RADIX;
02625     volatile double a, b, retval;
02626 
02627     if (expt < minexpt) {
02628         a = ldexp(fract, expt - mantBits - minexpt);
02629         b = ldexp(1.0, mantBits + minexpt);
02630         retval = a * b;
02631     } else {
02632         retval = ldexp(fract, expt);
02633     }
02634     return retval;
02635 }
02636 
02637 /*
02638  *----------------------------------------------------------------------
02639  *
02640  * TclFormatNaN --
02641  *
02642  *      Makes the string representation of a "Not a Number"
02643  *
02644  * Results:
02645  *      None.
02646  *
02647  * Side effects:
02648  *      Stores the string representation in the supplied buffer, which must be
02649  *      at least TCL_DOUBLE_SPACE characters.
02650  *
02651  *----------------------------------------------------------------------
02652  */
02653 
02654 void
02655 TclFormatNaN(
02656     double value,               /* The Not-a-Number to format. */
02657     char *buffer)               /* String representation. */
02658 {
02659 #ifndef IEEE_FLOATING_POINT
02660     strcpy(buffer, "NaN");
02661     return;
02662 #else
02663     union {
02664         double dv;
02665         Tcl_WideUInt iv;
02666     } bitwhack;
02667 
02668     bitwhack.dv = value;
02669     if (n770_fp) {
02670         bitwhack.iv = Nokia770Twiddle(bitwhack.iv);
02671     }
02672     if (bitwhack.iv & ((Tcl_WideUInt) 1 << 63)) {
02673         bitwhack.iv &= ~ ((Tcl_WideUInt) 1 << 63);
02674         *buffer++ = '-';
02675     }
02676     *buffer++ = 'N';
02677     *buffer++ = 'a';
02678     *buffer++ = 'N';
02679     bitwhack.iv &= (((Tcl_WideUInt) 1) << 51) - 1;
02680     if (bitwhack.iv != 0) {
02681         sprintf(buffer, "(%" TCL_LL_MODIFIER "x)", bitwhack.iv);
02682     } else {
02683         *buffer = '\0';
02684     }
02685 #endif /* IEEE_FLOATING_POINT */
02686 }
02687 
02688 /*
02689  *----------------------------------------------------------------------
02690  *
02691  * Nokia770Twiddle --
02692  *
02693  *      Transpose the two words of a number for Nokia 770 floating
02694  *      point handling.
02695  *
02696  *----------------------------------------------------------------------
02697  */
02698 
02699 static Tcl_WideUInt
02700 Nokia770Twiddle(
02701     Tcl_WideUInt w)             /* Number to transpose */
02702 {
02703     return (((w >> 32) & 0xffffffff) | (w << 32));
02704 }
02705 
02706 /*
02707  *----------------------------------------------------------------------
02708  *
02709  * TclNokia770Doubles --
02710  *
02711  *      Transpose the two words of a number for Nokia 770 floating
02712  *      point handling.
02713  *
02714  *----------------------------------------------------------------------
02715  */
02716 
02717 int
02718 TclNokia770Doubles(void)
02719 {
02720     return n770_fp;
02721 }
02722 
02723 /*
02724  * Local Variables:
02725  * mode: c
02726  * c-basic-offset: 4
02727  * fill-column: 78
02728  * End:
02729  */



Generated on Wed Mar 12 12:18:21 2008 by  doxygen 1.5.1