aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <Administrator@.(none)>2011-12-14 10:01:57 +1000
committerSteve Bennett <steveb@workware.net.au>2011-12-16 13:10:13 +1000
commitb6ca9c7ed71cb4b612dee89b5569cbf599bfc386 (patch)
tree85146eded5b73c0646633c898715baf99a4ad2fa
parentd0ac7ddf7cd922aa4f9b691b6414c3c7f22b08f1 (diff)
downloadjimtcl-b6ca9c7ed71cb4b612dee89b5569cbf599bfc386.zip
jimtcl-b6ca9c7ed71cb4b612dee89b5569cbf599bfc386.tar.gz
jimtcl-b6ca9c7ed71cb4b612dee89b5569cbf599bfc386.tar.bz2
Fix double to string on mingw
The MS CRT always produces a 3 digit exponent for %e And update [format] tests to account for this difference
-rw-r--r--jim-win32compat.h3
-rw-r--r--jim.c43
-rw-r--r--tests/format.test92
3 files changed, 74 insertions, 64 deletions
diff --git a/jim-win32compat.h b/jim-win32compat.h
index 8dc0bde..717642c 100644
--- a/jim-win32compat.h
+++ b/jim-win32compat.h
@@ -12,6 +12,9 @@ int dlclose(void *handle);
void *dlsym(void *handle, const char *symbol);
char *dlerror(void);
+/* MS CRT always uses three digits after 'e' */
+#define JIM_SPRINTF_DOUBLE_NEEDS_FIX
+
#ifdef _MSC_VER
/* These are msvc vs gcc */
diff --git a/jim.c b/jim.c
index 88bf0c2..4189919 100644
--- a/jim.c
+++ b/jim.c
@@ -452,33 +452,40 @@ int Jim_StringToWide(const char *str, jim_wide * widePtr, int base)
int Jim_DoubleToString(char *buf, double doubleValue)
{
int len;
- char *buf0 = buf;
+ int i;
len = sprintf(buf, "%.12g", doubleValue);
- /* Add a final ".0" if it's a number. But not
- * for NaN or InF */
- while (*buf) {
- if (*buf == '.' || isalpha(UCHAR(*buf))) {
- /* inf -> Inf, nan -> Nan */
- if (*buf == 'i' || *buf == 'n') {
- *buf = toupper(UCHAR(*buf));
- }
- if (*buf == 'I') {
- /* Infinity -> Inf */
- buf[3] = '\0';
- len = buf - buf0 + 3;
+ /* Add a final ".0" if necessary */
+ for (i = 0; i < len; i++) {
+ if (buf[i] == '.' || buf[i] == 'e') {
+#if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX)
+ /* If 'buf' ends in e-0nn or e+0nn, remove
+ * the 0 after the + or - and reduce the length by 1
+ */
+ char *e = strchr(buf, 'e');
+ if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') {
+ /* Move it up */
+ e += 2;
+ memmove(e, e + 1, len - (e - buf));
+ return len - 1;
}
+#endif
return len;
}
- buf++;
+ /* inf or Infinity -> Inf, nan -> Nan */
+ if (buf[i] == 'i' || buf[i] == 'I' || buf[i] == 'n' || buf[i] == 'N') {
+ buf[i] = toupper(UCHAR(buf[i]));
+ buf[i + 3] = 0;
+ return i + 3;
+ }
}
- *buf++ = '.';
- *buf++ = '0';
- *buf = '\0';
+ buf[i++] = '.';
+ buf[i++] = '0';
+ buf[i] = '\0';
- return len + 2;
+ return i;
}
int Jim_StringToDouble(const char *str, double *doublePtr)
diff --git a/tests/format.test b/tests/format.test
index 475be48..28509ca 100644
--- a/tests/format.test
+++ b/tests/format.test
@@ -125,32 +125,32 @@ test format-3.1 {Tcl_FormatObjCmd: character formatting} utf8 {
test format-3.2 {Tcl_FormatObjCmd: international character formatting} utf8 {
format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 0xa2 0x4e4e 0x25a 0xc3 0xff08 0 3 0x6575 -4 0x4e4f
} "|\ua2|\u4e4e|\u25a|\uc3|\uff08 | \0| \u6575|\u4e4f |"
-test format-4.1 {e and f formats} {
+test format-4.1 {e and f formats} -body {
format "%e %e %e %e" 34.2e12 68.514 -.125 -16000. .000053
-} {3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
-test format-4.2 {e and f formats} {
+} -match regexp -result {3.420000e\+0?13 6.851400e\+0?01 -1.250000e-0?01 -1.600000e\+0?04}
+test format-4.2 {e and f formats} -body {
format "%20e %20e %20e %20e" 34.2e12 68.514 -.125 -16000. .000053
-} { 3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
-if {!$roundOffBug} {
- test format-4.3 {e and f formats} {
- format "%.1e %.1e %.1e %.1e" 34.2e12 68.514 -.126 -16000. .000053
- } {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
- test format-4.4 {e and f formats} {
- format "%020e %020e %020e %020e" 34.2e12 68.514 -.126 -16000. .000053
- } {000000003.420000e+13 000000006.851400e+01 -00000001.260000e-01 -00000001.600000e+04}
- test format-4.5 {e and f formats} {
- format "%7.1e %7.1e %7.1e %7.1e" 34.2e12 68.514 -.126 -16000. .000053
- } {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
- test format-4.6 {e and f formats} {
- format "%f %f %f %f" 34.2e12 68.514 -.125 -16000. .000053
- } {34200000000000.000000 68.514000 -0.125000 -16000.000000}
-}
+} -match regexp -result {( 3.420000e\+13 6.851400e\+01 -1.250000e-01 -1.600000e\+04| 3.420000e\+013 6.851400e\+001 -1.250000e-001 -1.600000e\+004)}
+
+test format-4.3 {e and f formats} -body {
+ format "%.1e %.1e %.1e %.1e" 34.2e12 68.514 -.126 -16000. .000053
+} -match regexp -result {3.4e\+0?13 6.9e\+0?01 -1.3e-0?01 -1.6e\+0?04}
+test format-4.4 {e and f formats} -body {
+ format "%020e %020e %020e %020e" 34.2e12 68.514 -.126 -16000. .000053
+} -match regexp -result {(000000003.420000e\+13 000000006.851400e\+01 -00000001.260000e-01 -00000001.600000e\+04|00000003.420000e\+013 00000006.851400e\+001 -0000001.260000e-001 -0000001.600000e\+004)}
+
+test format-4.5 {e and f formats} -body {
+ format "%7.1e %7.1e %7.1e %7.1e" 34.2e12 68.514 -.126 -16000. .000053
+} -match regexp -result {3.4e\+0?13 6.9e\+0?01 -1.3e-0?01 -1.6e\+0?04}
+test format-4.6 {e and f formats} {
+ format "%f %f %f %f" 34.2e12 68.514 -.125 -16000. .000053
+} {34200000000000.000000 68.514000 -0.125000 -16000.000000}
test format-4.7 {e and f formats} {
format "%.4f %.4f %.4f %.4f %.4f" 34.2e12 68.514 -.125 -16000. .000053
} {34200000000000.0000 68.5140 -0.1250 -16000.0000 0.0001}
-test format-4.8 {e and f formats} {
+test format-4.8 {e and f formats} -body {
format "%.4e %.5e %.6e" -9.99996 -9.99996 9.99996
-} {-1.0000e+01 -9.99996e+00 9.999960e+00}
+} -match regexp -result {\-1.0000e\+0?01 -9.99996e\+0?00 9.999960e\+0?00}
test format-4.9 {e and f formats} {
format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
} {-10.0000 -9.99996 9.999960}
@@ -160,9 +160,9 @@ test format-4.10 {e and f formats} {
test format-4.11 {e and f formats} {
format "%-020f %020f" -9.99996 -9.99996 9.99996
} {-9.999960 -000000000009.999960}
-test format-4.12 {e and f formats} {
+test format-4.12 {e and f formats} -body {
format "%.0e %#.0e" -9.99996 -9.99996 9.99996
-} {-1e+01 -1.e+01}
+} -match regexp -result {\-1e\+0?01 -1.e\+0?01}
test format-4.13 {e and f formats} {
format "%.0f %#.0f" -9.99996 -9.99996 9.99996
} {-10 -10.}
@@ -176,12 +176,12 @@ test format-4.16 {e and f formats} {
format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
} {0.0 0.1 0.0 0.0}
-test format-5.1 {g-format} {
+test format-5.1 {g-format} -body {
format "%.3g" 12341.0
-} {1.23e+04}
-test format-5.2 {g-format} {
+} -match regexp -result {1.23e\+0?04}
+test format-5.2 {g-format} -body {
format "%.3G" 1234.12345
-} {1.23E+03}
+} -match regexp -result {1.23E\+0?03}
test format-5.3 {g-format} {
format "%.3g" 123.412345
} {123}
@@ -206,12 +206,12 @@ test format-5.9 {g-format} {
test format-5.10 {g-format} {
format "%.3g" .00012341
} {0.000123}
-test format-5.11 {g-format} {
+test format-5.11 {g-format} -body {
format "%.3g" .00001234
-} {1.23e-05}
-test format-5.12 {g-format} {
+} -match regexp -result {1.23e-0?05}
+test format-5.12 {g-format} -body {
format "%.4g" 9999.6
-} {1e+04}
+} -match regexp -result {1e\+0?04}
test format-5.13 {g-format} {
format "%.4g" 999.96
} {1000}
@@ -227,31 +227,31 @@ test format-5.16 {g-format} {
test format-5.17 {g-format} {
format "%.3g" .001
} {0.001}
-test format-5.18 {g-format} {
+test format-5.18 {g-format} -body {
format "%.3g" .00001
-} {1e-05}
-test format-5.19 {g-format} {
+} -match regexp -result {1e-0?05}
+test format-5.19 {g-format} -body {
format "%#.3g" 1234.0
-} {1.23e+03}
-test format-5.20 {g-format} {
+} -match regexp -result {1.23e\+0?03}
+test format-5.20 {g-format} -body {
format "%#.3G" 9999.5
-} {1.00E+04}
+} -match regexp -result {1.00E\+0?04}
-test format-6.1 {floating-point zeroes} {
+test format-6.1 {floating-point zeroes} -body {
format "%e %f %g" 0.0 0.0 0.0 0.0
-} {0.000000e+00 0.000000 0}
-test format-6.2 {floating-point zeroes} {
+} -match regexp -result {0.000000e\+0?00 0.000000 0}
+test format-6.2 {floating-point zeroes} -body {
format "%.4e %.4f %.4g" 0.0 0.0 0.0 0.0
-} {0.0000e+00 0.0000 0}
-test format-6.3 {floating-point zeroes} {
+} -match regexp -result {0.0000e\+0?00 0.0000 0}
+test format-6.3 {floating-point zeroes} -body {
format "%#.4e %#.4f %#.4g" 0.0 0.0 0.0 0.0
-} {0.0000e+00 0.0000 0.000}
-test format-6.4 {floating-point zeroes} {
+} -match regexp -result {0.0000e\+0?00 0.0000 0.000}
+test format-6.4 {floating-point zeroes} -body {
format "%.0e %.0f %.0g" 0.0 0.0 0.0 0.0
-} {0e+00 0 0}
-test format-6.5 {floating-point zeroes} {
+} -match regexp -result {0e\+0?00 0 0}
+test format-6.5 {floating-point zeroes} -body {
format "%#.0e %#.0f %#.0g" 0.0 0.0 0.0 0.0
-} {0.e+00 0. 0.}
+} -match regexp -result {0.e\+0?00 0. 0.}
test format-6.6 {floating-point zeroes} {
format "%3.0f %3.0f %3.0f %3.0f" 0.0 0.0 0.0 0.0
} { 0 0 0 0}