summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2012-12-10 04:32:13 (GMT)
committerdgp <dgp@users.sourceforge.net>2012-12-10 04:32:13 (GMT)
commit6569c1296649af791d6392751df2e1a15e5c5f24 (patch)
tree75dd49031467d624d8c3ad2f9f8725b367933f3a
parentc69e1e2500a8de36ee29f0220170bddaf320b3f1 (diff)
downloadtcl-novem_numbers_eias.zip
tcl-novem_numbers_eias.tar.gz
tcl-novem_numbers_eias.tar.bz2
WIP getting rid of the ::tcl_precision variablenovem_numbers_eias
-rw-r--r--doc/PrintDbl.39
-rw-r--r--doc/tclvars.n57
-rw-r--r--generic/tcl.h6
-rw-r--r--generic/tclBasic.c3
-rw-r--r--generic/tclCompExpr.c2
-rw-r--r--generic/tclInt.decls8
-rw-r--r--generic/tclIntDecls.h10
-rw-r--r--generic/tclObj.c5
-rwxr-xr-xgeneric/tclStrToD.c4
-rw-r--r--generic/tclStubInit.c2
-rw-r--r--generic/tclUtil.c158
-rw-r--r--tests/basic.test1
-rw-r--r--tests/util.test8
13 files changed, 34 insertions, 239 deletions
diff --git a/doc/PrintDbl.3 b/doc/PrintDbl.3
index 99b0113..baa415c 100644
--- a/doc/PrintDbl.3
+++ b/doc/PrintDbl.3
@@ -18,10 +18,7 @@ Tcl_PrintDouble \- Convert floating value to string
.SH ARGUMENTS
.AS Tcl_Interp *interp out
.AP Tcl_Interp *interp in
-Before Tcl 8.0, the \fBtcl_precision\fR variable in this interpreter
-controlled the conversion. As of Tcl 8.0, this argument is ignored and
-the conversion is controlled by the \fBtcl_precision\fR variable
-that is now shared by all interpreters.
+This argument is ignored.
.AP double value in
Floating-point value to be converted.
.AP char *dst out
@@ -41,9 +38,7 @@ so that it does not look like an integer. Where \fB%g\fR would
generate an integer with no decimal point, \fBTcl_PrintDouble\fR adds
.QW .0 .
.PP
-If the \fBtcl_precision\fR value is non-zero, the result will have
-precisely that many digits of significance. If the value is zero
-(the default), the result will have the fewest digits needed to
+The string generated has the fewest digits needed to
represent the number in such a way that \fBTcl_NewDoubleObj\fR
will generate the same number when presented with the given string.
IEEE semantics of rounding to even apply to the conversion.
diff --git a/doc/tclvars.n b/doc/tclvars.n
index 44a8e11..2ea08c9 100644
--- a/doc/tclvars.n
+++ b/doc/tclvars.n
@@ -10,7 +10,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-argc, argv, argv0, auto_path, env, errorCode, errorInfo, tcl_interactive, tcl_library, tcl_nonwordchars, tcl_patchLevel, tcl_pkgPath, tcl_platform, tcl_precision, tcl_rcFileName, tcl_traceCompile, tcl_traceEval, tcl_wordchars, tcl_version \- Variables used by Tcl
+argc, argv, argv0, auto_path, env, errorCode, errorInfo, tcl_interactive, tcl_library, tcl_nonwordchars, tcl_patchLevel, tcl_pkgPath, tcl_platform, tcl_rcFileName, tcl_traceCompile, tcl_traceEval, tcl_wordchars, tcl_version \- Variables used by Tcl
.BE
.SH DESCRIPTION
.PP
@@ -356,61 +356,6 @@ This gives the size of the native-machine word in bytes (strictly, it
is same as the result of evaluating \fIsizeof(long)\fR in C.)
.RE
.TP
-\fBtcl_precision\fR
-.
-This variable controls the number of digits to generate
-when converting floating-point values to strings. It defaults
-to 0. \fIApplications should not change this value;\fR it is
-provided for compatibility with legacy code.
-.PP
-.RS
-The default value of 0 is special, meaning that Tcl should
-convert numbers using as few digits as possible while still
-distinguishing any floating point number from its nearest
-neighbours. It differs from using an arbitrarily high value
-for \fItcl_precision\fR in that an inexact number like \fI1.4\fR
-will convert as \fI1.4\fR rather than \fI1.3999999999999999\fR
-even though the latter is nearer to the exact value of the
-binary number.
-.RE
-.PP
-.RS
-If \fBtcl_precision\fR is not zero, then when Tcl converts a floating
-point number, it creates a decimal representation of at most
-\fBtcl_precision\fR significant digits; the result may be shorter if
-the shorter result represents the original number exactly. If no
-result of at most \fBtcl_precision\fR digits is an exact representation
-of the original number, the one that is closest to the original
-number is chosen.
-If the original number lies precisely between two equally accurate
-decimal representations, then the one with an even value for the least
-significant digit is chosen; for instance, if \fBtcl_precision\fR is 3, then
-0.3125 will convert to 0.312, not 0.313, while 0.6875 will convert to
-0.688, not 0.687. Any string of trailing zeroes that remains is trimmed.
-.RE
-.PP
-.RS
-a \fBtcl_precision\fR value of 17 digits is
-.QW perfect
-for IEEE floating-point in that it allows
-double-precision values to be converted to strings and back to
-binary with no loss of information. For this reason, you will often
-see it as a value in legacy code that must run on Tcl versions before
-8.5. It is no longer recommended; as noted above, a zero value is the
-preferred method.
-.RE
-.PP
-.RS
-All interpreters in a thread share a single \fBtcl_precision\fR value:
-changing it in one interpreter will affect all other interpreters as
-well. Safe interpreters are not allowed to modify the
-variable.
-.RE
-.PP
-.RS
-Valid values for \fBtcl_precision\fR range from 0 to 17.
-.RE
-.TP
\fBtcl_rcFileName\fR
.
This variable is used during initialization to indicate the name of a
diff --git a/generic/tcl.h b/generic/tcl.h
index 162983b..bfcc750 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -827,9 +827,9 @@ typedef struct Tcl_DString {
#define Tcl_DStringValue(dsPtr) ((dsPtr)->string)
/*
- * Definitions for the maximum number of digits of precision that may be
- * specified in the "tcl_precision" variable, and the number of bytes of
- * buffer space required by Tcl_PrintDouble.
+ * Definitions for the maximum number of decimal digits of precision that may
+ * stored in a double, and the number of bytes of buffer space required by
+ * Tcl_PrintDouble.
*/
#define TCL_MAX_PREC 17
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 7202184..0b75fc8 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -897,9 +897,6 @@ Tcl_CreateInterp(void)
Tcl_SetVar(interp, "tcl_patchLevel", TCL_PATCH_LEVEL, TCL_GLOBAL_ONLY);
Tcl_SetVar(interp, "tcl_version", TCL_VERSION, TCL_GLOBAL_ONLY);
- Tcl_TraceVar2(interp, "tcl_precision", NULL,
- TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
- TclPrecTraceProc, NULL);
TclpSetVariables(interp);
#ifdef TCL_THREADS
diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c
index 890d518..960ce9f 100644
--- a/generic/tclCompExpr.c
+++ b/generic/tclCompExpr.c
@@ -2339,10 +2339,12 @@ CompileExprTree(
switch (nodePtr->lexeme) {
case START:
case QUESTION:
+#if 1
if (convert && (nodePtr == rootPtr)) {
TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);
}
break;
+#endif
case OPEN_PAREN:
/* do nothing */
diff --git a/generic/tclInt.decls b/generic/tclInt.decls
index 8c46e55..3d9b1d9 100644
--- a/generic/tclInt.decls
+++ b/generic/tclInt.decls
@@ -359,10 +359,10 @@ declare 81 {
# declare 87 {
# void TclPlatformInit(Tcl_Interp *interp)
# }
-declare 88 {
- char *TclPrecTraceProc(ClientData clientData, Tcl_Interp *interp,
- const char *name1, const char *name2, int flags)
-}
+#declare 88 {
+# char *TclPrecTraceProc(ClientData clientData, Tcl_Interp *interp,
+# const char *name1, const char *name2, int flags)
+#}
declare 89 {
int TclPreventAliasLoop(Tcl_Interp *interp, Tcl_Interp *cmdInterp,
Tcl_Command cmd)
diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h
index 65b1888..2b1f5c3 100644
--- a/generic/tclIntDecls.h
+++ b/generic/tclIntDecls.h
@@ -210,10 +210,7 @@ TCLAPI char * TclpRealloc(char *ptr, unsigned int size);
/* Slot 85 is reserved */
/* Slot 86 is reserved */
/* Slot 87 is reserved */
-/* 88 */
-TCLAPI char * TclPrecTraceProc(ClientData clientData,
- Tcl_Interp *interp, const char *name1,
- const char *name2, int flags);
+/* Slot 88 is reserved */
/* 89 */
TCLAPI int TclPreventAliasLoop(Tcl_Interp *interp,
Tcl_Interp *cmdInterp, Tcl_Command cmd);
@@ -673,7 +670,7 @@ typedef struct TclIntStubs {
void (*reserved85)(void);
void (*reserved86)(void);
void (*reserved87)(void);
- char * (*tclPrecTraceProc) (ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); /* 88 */
+ void (*reserved88)(void);
int (*tclPreventAliasLoop) (Tcl_Interp *interp, Tcl_Interp *cmdInterp, Tcl_Command cmd); /* 89 */
void (*reserved90)(void);
void (*tclProcCleanupProc) (Proc *procPtr); /* 91 */
@@ -983,8 +980,7 @@ extern const TclIntStubs *tclIntStubsPtr;
/* Slot 85 is reserved */
/* Slot 86 is reserved */
/* Slot 87 is reserved */
-#define TclPrecTraceProc \
- (tclIntStubsPtr->tclPrecTraceProc) /* 88 */
+/* Slot 88 is reserved */
#define TclPreventAliasLoop \
(tclIntStubsPtr->tclPreventAliasLoop) /* 89 */
/* Slot 90 is reserved */
diff --git a/generic/tclObj.c b/generic/tclObj.c
index 74cb29e..3a36375 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -2329,10 +2329,7 @@ SetDoubleFromAny(
* UpdateStringOfDouble --
*
* Update the string representation for a double-precision floating point
- * object. This must obey the current tcl_precision value for
- * double-to-string conversions. Note: This function does not free an
- * existing old string rep so storage will be lost if this has not
- * already been done.
+ * object.
*
* Results:
* None.
diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c
index 2287a16..3edff7a 100755
--- a/generic/tclStrToD.c
+++ b/generic/tclStrToD.c
@@ -3934,8 +3934,8 @@ StrictBignumConversion(
* This function is a service routine that produces the string of digits for
* floating-point-to-decimal conversion. It can do a number of things
* according to the 'flags' argument. Valid values for 'flags' include:
- * TCL_DD_SHORTEST - This is the default for floating point conversion if
- * ::tcl_precision is 0. It constructs the shortest string of
+ * TCL_DD_SHORTEST - This is the default for floating point conversion
+ * It constructs the shortest string of
* digits that will reconvert to the given number when scanned.
* For floating point numbers that are exactly between two
* decimal numbers, it resolves using the 'round to even' rule.
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index c836f45..daae7f5 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -262,7 +262,7 @@ static const TclIntStubs tclIntStubs = {
0, /* 85 */
0, /* 86 */
0, /* 87 */
- TclPrecTraceProc, /* 88 */
+ 0, /* 88 */
TclPreventAliasLoop, /* 89 */
0, /* 90 */
TclProcCleanupProc, /* 91 */
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 4b69628..2131cfe 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -93,13 +93,6 @@ static ProcessGlobalValue executableName = {
#define CONVERT_ANY 16
/*
- * The following key is used by Tcl_PrintDouble and TclPrecTraceProc to
- * access the precision to be used for double formatting.
- */
-
-static Tcl_ThreadDataKey precisionKey;
-
-/*
* Prototypes for functions defined later in this file.
*/
@@ -2920,10 +2913,9 @@ Tcl_DStringEndSublist(
* string using.
*
* Results:
- * The ASCII equivalent of "value" is written at "dst". It is written
- * using the current precision, and it is guaranteed to contain a decimal
- * point or exponent, so that it looks like a floating-point value and
- * not an integer.
+ * The ASCII equivalent of "value" is written at "dst". It is guaranteed
+ * to contain a decimal point or exponent, so that it looks like a
+ * floating-point value and not an integer.
*
* Side effects:
* None.
@@ -2933,9 +2925,7 @@ Tcl_DStringEndSublist(
void
Tcl_PrintDouble(
- Tcl_Interp *interp, /* Interpreter whose tcl_precision variable
- * used to be used to control printing. It's
- * ignored now. */
+ Tcl_Interp *interp, /* Ignored. */
double value, /* Value to print as string. */
char *dst) /* Where to store converted value; must have
* at least TCL_DOUBLE_SPACE characters. */
@@ -2945,7 +2935,6 @@ Tcl_PrintDouble(
int signum;
char *digits;
char *end;
- int *precisionPtr = Tcl_GetThreadData(&precisionKey, (int) sizeof(int));
/*
* Handle NaN.
@@ -2977,53 +2966,8 @@ Tcl_PrintDouble(
* Ordinary (normal and denormal) values.
*/
- if (*precisionPtr == 0) {
- digits = TclDoubleDigits(value, -1, TCL_DD_SHORTEST,
- &exponent, &signum, &end);
- } else {
- /*
- * There are at least two possible interpretations for tcl_precision.
- *
- * The first is, "choose the decimal representation having
- * $tcl_precision digits of significance that is nearest to the given
- * number, breaking ties by rounding to even, and then trimming
- * trailing zeros." This gives the greatest possible precision in the
- * decimal string, but offers the anomaly that [expr 0.1] will be
- * "0.10000000000000001".
- *
- * The second is "choose the decimal representation having at most
- * $tcl_precision digits of significance that is nearest to the given
- * number. If no such representation converts exactly to the given
- * number, choose the one that is closest, breaking ties by rounding
- * to even. If more than one such representation converts exactly to
- * the given number, choose the shortest, breaking ties in favour of
- * the nearest, breaking remaining ties in favour of the one ending in
- * an even digit."
- *
- * Tcl 8.4 implements the first of these, which gives rise to
- * anomalies in formatting:
- *
- * % expr 0.1
- * 0.10000000000000001
- * % expr 0.01
- * 0.01
- * % expr 1e-7
- * 9.9999999999999995e-08
- *
- * For human readability, it appears better to choose the second rule,
- * and let [expr 0.1] return 0.1. But for 8.4 compatibility, we prefer
- * the first (the recommended zero value for tcl_precision avoids the
- * problem entirely).
- *
- * Uncomment TCL_DD_SHORTEN_FLAG in the next call to prefer the method
- * that allows floating point values to be shortened if it can be done
- * without loss of precision.
- */
-
- digits = TclDoubleDigits(value, *precisionPtr,
- TCL_DD_E_FORMAT /* | TCL_DD_SHORTEN_FLAG */,
- &exponent, &signum, &end);
- }
+ digits = TclDoubleDigits(value, -1, TCL_DD_SHORTEST, &exponent,
+ &signum, &end);
if (signum) {
*dst++ = '-';
}
@@ -3042,17 +2986,7 @@ Tcl_PrintDouble(
c = *++p;
}
}
-
- /*
- * Tcl 8.4 appears to format with at least a two-digit exponent;
- * preserve that behaviour when tcl_precision != 0
- */
-
- if (*precisionPtr == 0) {
- sprintf(dst, "e%+d", exponent);
- } else {
- sprintf(dst, "e%+03d", exponent);
- }
+ sprintf(dst, "e%+d", exponent);
} else {
/*
* F format for others.
@@ -3090,84 +3024,6 @@ Tcl_PrintDouble(
/*
*----------------------------------------------------------------------
*
- * TclPrecTraceProc --
- *
- * This function is invoked whenever the variable "tcl_precision" is
- * written.
- *
- * Results:
- * Returns NULL if all went well, or an error message if the new value
- * for the variable doesn't make sense.
- *
- * Side effects:
- * If the new value doesn't make sense then this function undoes the
- * effect of the variable modification. Otherwise it modifies the format
- * string that's used by Tcl_PrintDouble.
- *
- *----------------------------------------------------------------------
- */
-
- /* ARGSUSED */
-char *
-TclPrecTraceProc(
- ClientData clientData, /* Not used. */
- Tcl_Interp *interp, /* Interpreter containing variable. */
- const char *name1, /* Name of variable. */
- const char *name2, /* Second part of variable name. */
- int flags) /* Information about what happened. */
-{
- Tcl_Obj *value;
- int prec;
- int *precisionPtr = Tcl_GetThreadData(&precisionKey, (int) sizeof(int));
-
- /*
- * If the variable is unset, then recreate the trace.
- */
-
- if (flags & TCL_TRACE_UNSETS) {
- if ((flags & TCL_TRACE_DESTROYED) && !Tcl_InterpDeleted(interp)) {
- Tcl_TraceVar2(interp, name1, name2,
- TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES
- |TCL_TRACE_UNSETS, TclPrecTraceProc, clientData);
- }
- return NULL;
- }
-
- /*
- * When the variable is read, reset its value from our shared value. This
- * is needed in case the variable was modified in some other interpreter
- * so that this interpreter's value is out of date.
- */
-
-
- if (flags & TCL_TRACE_READS) {
- Tcl_SetVar2Ex(interp, name1, name2, Tcl_NewIntObj(*precisionPtr),
- flags & TCL_GLOBAL_ONLY);
- return NULL;
- }
-
- /*
- * The variable is being written. Check the new value and disallow it if
- * it isn't reasonable or if this is a safe interpreter (we don't want
- * safe interpreters messing up the precision of other interpreters).
- */
-
- if (Tcl_IsSafe(interp)) {
- return (char *) "can't modify precision from a safe interpreter";
- }
- value = Tcl_GetVar2Ex(interp, name1, name2, flags & TCL_GLOBAL_ONLY);
- if (value == NULL
- || Tcl_GetIntFromObj(NULL, value, &prec) != TCL_OK
- || prec < 0 || prec > TCL_MAX_PREC) {
- return (char *) "improper value for precision";
- }
- *precisionPtr = prec;
- return NULL;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* TclNeedSpace --
*
* This function checks to see whether it is appropriate to add a space
diff --git a/tests/basic.test b/tests/basic.test
index 7435571..8db950c 100644
--- a/tests/basic.test
+++ b/tests/basic.test
@@ -868,6 +868,7 @@ test basic-48.16.$noComp {expansion: testing for leaks} -setup {
rename stress {}
} -result 0
+set ::tcl_precision 0
test basic-48.17.$noComp {expansion: object safety} -setup {
set old_precision $::tcl_precision
set ::tcl_precision 4
diff --git a/tests/util.test b/tests/util.test
index 0e50483..f428ee9 100644
--- a/tests/util.test
+++ b/tests/util.test
@@ -383,6 +383,7 @@ test util-5.51 {Tcl_StringMatch} {
Wrapper_Tcl_StringMatch "" ""
} 1
+if 0 {
test util-6.1 {Tcl_PrintDouble - using tcl_precision} -setup {
set old_precision $::tcl_precision
set ::tcl_precision 12
@@ -415,6 +416,7 @@ test util-6.4 {Tcl_PrintDouble - using tcl_precision} -setup {
} -cleanup {
set tcl_precision $old_precision
} -result {x1.1234}
+}
test util-6.5 {Tcl_PrintDouble - make sure there's a decimal point} {
concat x[expr 2.0]
} {x2.0}
@@ -422,6 +424,7 @@ test util-6.6 {Tcl_PrintDouble - make sure there's a decimal point} {
concat x[expr 3.0e98]
} {x3e+98}
+if 0 {
test util-7.1 {TclPrecTraceProc - unset callbacks} -setup {
set old_precision $::tcl_precision
} -body {
@@ -465,6 +468,7 @@ test util-7.4 {TclPrecTraceProc - write traces, bogus values} -setup {
} -cleanup {
set ::tcl_precision $old_precision
} -result {1 {can't set "tcl_precision": improper value for precision} 12}
+}
# This test always succeeded in the C locale anyway...
test util-8.1 {TclNeedSpace - correct UTF8 handling} {
@@ -2118,6 +2122,7 @@ test util-15.8 {smallest normal} {*}{
}
}
+if 0 {
set saved_precision $::tcl_precision
foreach ::tcl_precision {0 12} {
for {set e -312} {$e < -9} {incr e} {
@@ -3986,6 +3991,8 @@ test util-16.1.17.306 {8.4 compatible formatting of doubles} \
test util-16.1.17.307 {8.4 compatible formatting of doubles} \
{expr 1e307} \
9.9999999999999999e+306
+set ::tcl_precision $saved_precision
+}
test util-17.1 {bankers' rounding [Bug 3349507]} {ieeeFloatingPoint} {
set r {}
@@ -4016,7 +4023,6 @@ test util-17.1 {bankers' rounding [Bug 3349507]} {ieeeFloatingPoint} {
0x4400000000000000 0xc400000000000000
}]
-set ::tcl_precision $saved_precision
# cleanup
::tcltest::cleanupTests