summaryrefslogtreecommitdiffstats
path: root/generic/tclStrToD.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2018-10-28 19:36:34 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2018-10-28 19:36:34 (GMT)
commit1f6c360968fab22aa02a30a72c196a8f8eb19c0c (patch)
treec490d9cba824ba803b713fe06b6ccfb7f98caca3 /generic/tclStrToD.c
parent63b8d1466dca7693cf0f6b61d39fada6fd1e0e7f (diff)
parentccb97d88ffefe602e7eb5a9610bd356d66bc2f20 (diff)
downloadtcl-1f6c360968fab22aa02a30a72c196a8f8eb19c0c.zip
tcl-1f6c360968fab22aa02a30a72c196a8f8eb19c0c.tar.gz
tcl-1f6c360968fab22aa02a30a72c196a8f8eb19c0c.tar.bz2
Merge tip-468 branch
Diffstat (limited to 'generic/tclStrToD.c')
-rw-r--r--generic/tclStrToD.c159
1 files changed, 73 insertions, 86 deletions
diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c
index c7fdc5a..a46b29a 100644
--- a/generic/tclStrToD.c
+++ b/generic/tclStrToD.c
@@ -482,7 +482,7 @@ TclParseNumber(
{
enum State {
INITIAL, SIGNUM, ZERO, ZERO_X,
- ZERO_O, ZERO_B, BINARY,
+ ZERO_O, ZERO_B, ZERO_D, BINARY,
HEXADECIMAL, OCTAL, BAD_OCTAL, DECIMAL,
LEADING_RADIX_POINT, FRACTION,
EXPONENT_START, EXPONENT_SIGNUM, EXPONENT,
@@ -664,6 +664,10 @@ TclParseNumber(
state = ZERO_O;
break;
}
+ if (c == 'd' || c == 'D') {
+ state = ZERO_D;
+ break;
+ }
#ifdef TCL_NO_DEPRECATED
goto decimal;
#endif
@@ -707,7 +711,7 @@ TclParseNumber(
|| (octalSignificandWide >
(~(Tcl_WideUInt)0 >> shift)))) {
octalSignificandOverflow = 1;
- TclBNInitBignumFromWideUInt(&octalSignificandBig,
+ TclInitBignumFromWideUInt(&octalSignificandBig,
octalSignificandWide);
}
}
@@ -824,7 +828,7 @@ TclParseNumber(
((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
significandWide > (~(Tcl_WideUInt)0 >> shift))) {
significandOverflow = 1;
- TclBNInitBignumFromWideUInt(&significandBig,
+ TclInitBignumFromWideUInt(&significandBig,
significandWide);
}
}
@@ -865,7 +869,7 @@ TclParseNumber(
((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
significandWide > (~(Tcl_WideUInt)0 >> shift))) {
significandOverflow = 1;
- TclBNInitBignumFromWideUInt(&significandBig,
+ TclInitBignumFromWideUInt(&significandBig,
significandWide);
}
}
@@ -880,6 +884,16 @@ TclParseNumber(
state = BINARY;
break;
+ case ZERO_D:
+ if (c == '0') {
+ numTrailZeros++;
+ } else if ( ! isdigit(UCHAR(c))) {
+ goto endgame;
+ }
+ state = DECIMAL;
+ flags |= TCL_PARSE_INTEGER_ONLY;
+ /* FALLTHROUGH */
+
case DECIMAL:
/*
* Scanned an optional + or - followed by a string of decimal
@@ -1176,6 +1190,7 @@ TclParseNumber(
case ZERO_X:
case ZERO_O:
case ZERO_B:
+ case ZERO_D:
case LEADING_RADIX_POINT:
case EXPONENT_START:
case EXPONENT_SIGNUM:
@@ -1190,16 +1205,16 @@ TclParseNumber(
case sNA:
case sNANPAREN:
case sNANHEX:
+#endif
Tcl_Panic("TclParseNumber: bad acceptState %d parsing '%s'",
acceptState, bytes);
-#endif
case BINARY:
shift = numTrailZeros;
if (!significandOverflow && significandWide != 0 &&
((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
significandWide > (MOST_BITS + signum) >> shift)) {
significandOverflow = 1;
- TclBNInitBignumFromWideUInt(&significandBig, significandWide);
+ TclInitBignumFromWideUInt(&significandBig, significandWide);
}
if (shift) {
if (!significandOverflow) {
@@ -1220,7 +1235,7 @@ TclParseNumber(
((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
significandWide > (MOST_BITS + signum) >> shift)) {
significandOverflow = 1;
- TclBNInitBignumFromWideUInt(&significandBig, significandWide);
+ TclInitBignumFromWideUInt(&significandBig, significandWide);
}
if (shift) {
if (!significandOverflow) {
@@ -1241,7 +1256,7 @@ TclParseNumber(
((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
octalSignificandWide > (MOST_BITS + signum) >> shift)) {
octalSignificandOverflow = 1;
- TclBNInitBignumFromWideUInt(&octalSignificandBig,
+ TclInitBignumFromWideUInt(&octalSignificandBig,
octalSignificandWide);
}
if (shift) {
@@ -1253,32 +1268,18 @@ TclParseNumber(
}
}
if (!octalSignificandOverflow) {
- if (octalSignificandWide >
- (Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
-#ifndef TCL_WIDE_INT_IS_LONG
- if (octalSignificandWide <= (MOST_BITS + signum)) {
- objPtr->typePtr = &tclWideIntType;
- if (signum) {
- objPtr->internalRep.wideValue =
- - (Tcl_WideInt) octalSignificandWide;
- } else {
- objPtr->internalRep.wideValue =
- (Tcl_WideInt) octalSignificandWide;
- }
- break;
- }
-#endif
- TclBNInitBignumFromWideUInt(&octalSignificandBig,
+ if (octalSignificandWide > (MOST_BITS + signum)) {
+ TclInitBignumFromWideUInt(&octalSignificandBig,
octalSignificandWide);
octalSignificandOverflow = 1;
} else {
objPtr->typePtr = &tclIntType;
if (signum) {
- objPtr->internalRep.longValue =
- - (long) octalSignificandWide;
+ objPtr->internalRep.wideValue =
+ - (Tcl_WideInt) octalSignificandWide;
} else {
- objPtr->internalRep.longValue =
- (long) octalSignificandWide;
+ objPtr->internalRep.wideValue =
+ (Tcl_WideInt) octalSignificandWide;
}
}
}
@@ -1296,36 +1297,22 @@ TclParseNumber(
&significandWide, &significandBig, significandOverflow);
if (!significandOverflow && (significandWide > MOST_BITS+signum)){
significandOverflow = 1;
- TclBNInitBignumFromWideUInt(&significandBig, significandWide);
+ TclInitBignumFromWideUInt(&significandBig, significandWide);
}
returnInteger:
if (!significandOverflow) {
- if (significandWide >
- (Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
-#ifndef TCL_WIDE_INT_IS_LONG
- if (significandWide <= MOST_BITS+signum) {
- objPtr->typePtr = &tclWideIntType;
- if (signum) {
- objPtr->internalRep.wideValue =
- - (Tcl_WideInt) significandWide;
- } else {
- objPtr->internalRep.wideValue =
- (Tcl_WideInt) significandWide;
- }
- break;
- }
-#endif
- TclBNInitBignumFromWideUInt(&significandBig,
+ if (significandWide > MOST_BITS+signum) {
+ TclInitBignumFromWideUInt(&significandBig,
significandWide);
significandOverflow = 1;
} else {
objPtr->typePtr = &tclIntType;
if (signum) {
- objPtr->internalRep.longValue =
- - (long) significandWide;
+ objPtr->internalRep.wideValue =
+ - (Tcl_WideInt) significandWide;
} else {
- objPtr->internalRep.longValue =
- (long) significandWide;
+ objPtr->internalRep.wideValue =
+ (Tcl_WideInt) significandWide;
}
}
}
@@ -1470,7 +1457,7 @@ AccumulateDecimalDigit(
* bignum and fall through into the bignum case.
*/
- TclBNInitBignumFromWideUInt(bignumRepPtr, w);
+ TclInitBignumFromWideUInt(bignumRepPtr, w);
} else {
/*
* Wide multiplication.
@@ -1613,7 +1600,7 @@ MakeLowPrecisionDouble(
* call MakeHighPrecisionDouble to do it the hard way.
*/
- TclBNInitBignumFromWideUInt(&significandBig, significand);
+ TclInitBignumFromWideUInt(&significandBig, significand);
retval = MakeHighPrecisionDouble(0, &significandBig, numSigDigs,
exponent);
mp_clear(&significandBig);
@@ -1980,7 +1967,7 @@ RefineApproximation(
*----------------------------------------------------------------------
*/
-inline static void
+static inline void
MulPow5(
mp_int *base, /* Number to multiply. */
unsigned n, /* Power of 5 to multiply by. */
@@ -2025,7 +2012,7 @@ MulPow5(
*----------------------------------------------------------------------
*/
-inline static int
+static inline int
NormalizeRightward(
Tcl_WideUInt *wPtr) /* INOUT: Number to shift. */
{
@@ -2116,7 +2103,7 @@ RequiredPrecision(
*----------------------------------------------------------------------
*/
-inline static void
+static inline void
DoubleToExpAndSig(
double dv, /* Number to convert. */
Tcl_WideUInt *significand, /* OUTPUT: Significand of the number. */
@@ -2164,7 +2151,7 @@ DoubleToExpAndSig(
*----------------------------------------------------------------------
*/
-inline static void
+static inline void
TakeAbsoluteValue(
Double *d, /* Number to replace with absolute value. */
int *sign) /* Place to put the signum. */
@@ -2195,7 +2182,7 @@ TakeAbsoluteValue(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
FormatInfAndNaN(
Double *d, /* Exceptional number to format. */
int *decpt, /* Decimal point to set to a bogus value. */
@@ -2237,7 +2224,7 @@ FormatInfAndNaN(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
FormatZero(
int *decpt, /* Location of the decimal point. */
char **endPtr) /* Pointer to the end of the formatted data */
@@ -2267,7 +2254,7 @@ FormatZero(
*----------------------------------------------------------------------
*/
-inline static int
+static inline int
ApproximateLog10(
Tcl_WideUInt bw, /* Integer significand of the number. */
int be, /* Power of two to scale bw. */
@@ -2315,7 +2302,7 @@ ApproximateLog10(
*----------------------------------------------------------------------
*/
-inline static int
+static inline int
BetterLog10(
double d, /* Original number to format. */
int k, /* Characteristic(Log base 10) of the
@@ -2358,7 +2345,7 @@ BetterLog10(
*----------------------------------------------------------------------
*/
-inline static void
+static inline void
ComputeScale(
int be, /* Exponent part of number: d = bw * 2**be. */
int k, /* Characteristic of log10(number). */
@@ -2421,7 +2408,7 @@ ComputeScale(
*----------------------------------------------------------------------
*/
-inline static void
+static inline void
SetPrecisionLimits(
int convType, /* Type of conversion: TCL_DD_SHORTEST,
* TCL_DD_STEELE0, TCL_DD_E_FMT,
@@ -2482,7 +2469,7 @@ SetPrecisionLimits(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
BumpUp(
char *s, /* Cursor pointing one past the end of the
* string. */
@@ -2516,7 +2503,7 @@ BumpUp(
*----------------------------------------------------------------------
*/
-inline static int
+static inline int
AdjustRange(
double *dPtr, /* INOUT: Number to adjust. */
int k) /* IN: floor(log10(d)) */
@@ -2589,7 +2576,7 @@ AdjustRange(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
ShorteningQuickFormat(
double d, /* Number to convert. */
int k, /* floor(log10(d)) */
@@ -2664,7 +2651,7 @@ ShorteningQuickFormat(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
StrictQuickFormat(
double d, /* Number to convert. */
int k, /* floor(log10(d)) */
@@ -2738,7 +2725,7 @@ StrictQuickFormat(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
QuickConversion(
double e, /* Number to format. */
int k, /* floor(log10(d)), approximately. */
@@ -2843,7 +2830,7 @@ QuickConversion(
*----------------------------------------------------------------------
*/
-inline static void
+static inline void
CastOutPowersOf2(
int *b2, /* Power of 2 to multiply the significand. */
int *m2, /* Power of 2 to multiply 1/2 ulp. */
@@ -2887,7 +2874,7 @@ CastOutPowersOf2(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
ShorteningInt64Conversion(
Double *dPtr, /* Original number to convert. */
int convType, /* Type of conversion (shortest, Steele,
@@ -3056,7 +3043,7 @@ ShorteningInt64Conversion(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
StrictInt64Conversion(
Double *dPtr, /* Original number to convert. */
int convType, /* Type of conversion (shortest, Steele,
@@ -3162,7 +3149,7 @@ StrictInt64Conversion(
*----------------------------------------------------------------------
*/
-inline static int
+static inline int
ShouldBankerRoundUpPowD(
mp_int *b, /* Numerator of the fraction. */
int sd, /* Denominator is 2**(sd*DIGIT_BIT). */
@@ -3200,7 +3187,7 @@ ShouldBankerRoundUpPowD(
*----------------------------------------------------------------------
*/
-inline static int
+static inline int
ShouldBankerRoundUpToNextPowD(
mp_int *b, /* Numerator of the fraction. */
mp_int *m, /* Numerator of the rounding tolerance. */
@@ -3263,7 +3250,7 @@ ShouldBankerRoundUpToNextPowD(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
ShorteningBignumConversionPowD(
Double *dPtr, /* Original number to convert. */
int convType, /* Type of conversion (shortest, Steele,
@@ -3300,7 +3287,7 @@ ShorteningBignumConversionPowD(
* mminus = 5**m5
*/
- TclBNInitBignumFromWideUInt(&b, bw);
+ TclInitBignumFromWideUInt(&b, bw);
mp_init_set_int(&mminus, 1);
MulPow5(&b, b5, &b);
mp_mul_2d(&b, b2, &b);
@@ -3456,7 +3443,7 @@ ShorteningBignumConversionPowD(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
StrictBignumConversionPowD(
Double *dPtr, /* Original number to convert. */
int convType, /* Type of conversion (shortest, Steele,
@@ -3487,7 +3474,7 @@ StrictBignumConversionPowD(
* b = bw * 2**b2 * 5**b5
*/
- TclBNInitBignumFromWideUInt(&b, bw);
+ TclInitBignumFromWideUInt(&b, bw);
MulPow5(&b, b5, &b);
mp_mul_2d(&b, b2, &b);
@@ -3572,7 +3559,7 @@ StrictBignumConversionPowD(
*----------------------------------------------------------------------
*/
-inline static int
+static inline int
ShouldBankerRoundUp(
mp_int *twor, /* 2x the remainder from thd division that
* produced the last digit. */
@@ -3607,7 +3594,7 @@ ShouldBankerRoundUp(
*----------------------------------------------------------------------
*/
-inline static int
+static inline int
ShouldBankerRoundUpToNext(
mp_int *b, /* Remainder from the division that produced
* the last digit. */
@@ -3661,7 +3648,7 @@ ShouldBankerRoundUpToNext(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
ShorteningBignumConversion(
Double *dPtr, /* Original number being converted. */
int convType, /* Conversion type. */
@@ -3695,7 +3682,7 @@ ShorteningBignumConversion(
* S = 2**s2 * 5*s5
*/
- TclBNInitBignumFromWideUInt(&b, bw);
+ TclInitBignumFromWideUInt(&b, bw);
mp_mul_2d(&b, b2, &b);
mp_init_set_int(&S, 1);
MulPow5(&S, s5, &S); mp_mul_2d(&S, s2, &S);
@@ -3877,7 +3864,7 @@ ShorteningBignumConversion(
*----------------------------------------------------------------------
*/
-inline static char *
+static inline char *
StrictBignumConversion(
Double *dPtr, /* Original number being converted. */
int convType, /* Conversion type. */
@@ -3908,7 +3895,7 @@ StrictBignumConversion(
*/
mp_init_multi(&temp, &dig, NULL);
- TclBNInitBignumFromWideUInt(&b, bw);
+ TclInitBignumFromWideUInt(&b, bw);
mp_mul_2d(&b, b2, &b);
mp_init_set_int(&S, 1);
MulPow5(&S, s5, &S); mp_mul_2d(&S, s2, &S);
@@ -4556,7 +4543,7 @@ Tcl_InitBignumFromDouble(
return TCL_ERROR;
}
- fract = frexp(d,&expt);
+ fract = frexp(d, &expt);
if (expt <= 0) {
mp_init(b);
mp_zero(b);
@@ -4564,7 +4551,7 @@ Tcl_InitBignumFromDouble(
Tcl_WideInt w = (Tcl_WideInt) ldexp(fract, mantBits);
int shift = expt - mantBits;
- TclBNInitBignumFromWideInt(b, w);
+ TclInitBignumFromWideInt(b, w);
if (shift < 0) {
mp_div_2d(b, -shift, b, NULL);
} else if (shift > 0) {
@@ -4710,7 +4697,7 @@ TclCeil(
mp_int b;
mp_init(&b);
- if (mp_cmp_d(a, 0) == MP_LT) {
+ if (mp_isneg(a)) {
mp_neg(a, &b);
r = -TclFloor(&b);
} else {
@@ -4767,7 +4754,7 @@ TclFloor(
mp_int b;
mp_init(&b);
- if (mp_cmp_d(a, 0) == MP_LT) {
+ if (mp_isneg(a)) {
mp_neg(a, &b);
r = -TclCeil(&b);
} else {
@@ -4896,7 +4883,7 @@ Pow10TimesFrExp(
* Multiply by 10**exponent.
*/
- retval = frexp(retval * pow10vals[exponent&0xf], &j);
+ retval = frexp(retval * pow10vals[exponent & 0xf], &j);
expt += j;
for (i=4; i<9; ++i) {
if (exponent & (1<<i)) {