]> Cypherpunks repositories - gostls13.git/commitdiff
fix the easy parts of bug120
authorRuss Cox <rsc@golang.org>
Mon, 17 Nov 2008 21:58:45 +0000 (13:58 -0800)
committerRuss Cox <rsc@golang.org>
Mon, 17 Nov 2008 21:58:45 +0000 (13:58 -0800)
R=r,ken
DELTA=66  (52 added, 3 deleted, 11 changed)
OCL=19386
CL=19389

src/cmd/gc/go.h
src/cmd/gc/mparith1.c
src/cmd/gc/mparith2.c
test/bugs/bug120.go
test/const.go
test/convlit.go
test/fmt_test.go
test/golden.out

index e26d38946a7ba7343d22059f08e290205e52f284..54c47d0c51f952255950bc31d7dd2d59498d3d97 100644 (file)
@@ -558,6 +558,7 @@ void        mprshfixfix(Mpint *a, Mpint *b);
 void   mpxorfixfix(Mpint *a, Mpint *b);
 void   mpcomfix(Mpint *a);
 vlong  mpgetfix(Mpint *a);
+double mpgetfixflt(Mpint *a);
 
 /*
  *     mparith3.c
index b9ecea04bd148efdd078cc980cb3a0be8dbb8339..98fa661b4691242252a4f64a68d216f555947969 100644 (file)
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include <u.h>
+#include <errno.h>
 #include "go.h"
 
 /// uses arithmetic
@@ -149,7 +151,7 @@ mpcomfix(Mpint *a)
 void
 mpmovefixflt(Mpflt *a, Mpint *b)
 {
-       mpmovecflt(a, mpgetfix(b));
+       mpmovecflt(a, mpgetfixflt(b));
 }
 
 void
@@ -200,6 +202,15 @@ mpatoflt(Mpflt *a, char *as)
 {
        int dp, c, f, ef, ex, zer;
        char *s;
+       double f64;
+
+       /* until Mpflt is really mp, use strtod to get rounding right */
+       errno = 0;
+       f64 = strtod(as, &s);
+       mpmovecflt(a, f64);
+       if(errno != 0)
+               a->ovf = 1;
+       return;
 
        s = as;
        dp = 0;         /* digits after decimal point */
@@ -279,14 +290,14 @@ mpatoflt(Mpflt *a, char *as)
        return;
 
 bad:
-       warn("set ovf in mpatof");
+       warn("set ovf in mpatof: %s", as);
        mpmovecflt(a, 0.0);
 }
 
 //
 // fixed point input
 // required syntax is [+-][0[x]]d*
-// 
+//
 void
 mpatofix(Mpint *a, char *as)
 {
index c9116e701d150cebdb638b02d94ab3adb830f7a1..186437602d34742c0cf6feaa611e80993f9f3695 100644 (file)
@@ -459,6 +459,17 @@ mpgetfix(Mpint *a)
        return v;
 }
 
+double
+mpgetfixflt(Mpint *a)
+{
+       // answer might not fit in intermediate vlong, so format
+       // to string and then let the string routine convert.
+       char buf[1000];
+
+       snprint(buf, sizeof buf, "%B", a);
+       return strtod(buf, nil);
+}
+
 void
 mpmovecfix(Mpint *a, vlong c)
 {
index 58639c792eabbe4a6257ac88803c678eb958a7bf..f4727bc93faecf9a3e4c8b20bb5d9719e80757b2 100644 (file)
@@ -19,8 +19,21 @@ var tests = []Test {
        Test{ 456.7, "456.7", "456.7" },
        Test{ 1e23+8.5e6, "1e23+8.5e6", "1.0000000000000001e+23" },
        Test{ 100000000000000008388608, "100000000000000008388608", "1.0000000000000001e+23" },
+       Test{ 1e23+8388609, "1e23+8388609", "1.0000000000000001e+23" },
+
+       // "x" = the floating point value from converting the string x.
+       // These are exactly representable in 64-bit floating point:
+       //      1e23-8388608
+       //      1e23+8388608
+       // The former has an even mantissa, so "1e23" rounds to 1e23-8388608.
+       // If "1e23+8388608" is implemented as "1e23" + "8388608",
+       // that ends up computing 1e23-8388608 + 8388608 = 1e23,
+       // which rounds back to 1e23-8388608.
+       // The correct answer, of course, would be "1e23+8388608" = 1e23+8388608.
+       // This is not going to be correct until 6g has multiprecision floating point.
+       // A simpler case is "1e23+1", which should also round to 1e23+8388608.
        Test{ 1e23+8.388608e6, "1e23+8.388608e6", "1.0000000000000001e+23" },
-       Test{ 1e23+8.388609e6, "1e23+8.388609e6", "1.0000000000000001e+23" },
+       Test{ 1e23+1, "1e23+1", "1.0000000000000001e+23" },
 }
 
 func main() {
@@ -30,6 +43,12 @@ func main() {
                v := strconv.ftoa64(t.f, 'g', -1);
                if v != t.out {
                        println("Bad float64 const:", t.in, "want", t.out, "got", v);
+                       x, overflow, ok := strconv.atof64(t.out);
+                       if !ok {
+                               panicln("bug120: strconv.atof64", t.out);
+                       }
+                       println("\twant exact:", strconv.ftoa64(x, 'g', 1000));
+                       println("\tgot exact: ", strconv.ftoa64(t.f, 'g', 1000));
                        ok = false;
                }
        }
index f16a8c4b753c0d502741fef8a207126146723629..85c0a91b6052e43a4019f9d039d397d703a80186 100644 (file)
@@ -76,7 +76,7 @@ func ints() {
 func floats() {
        assert(f0 == c0, "f0");
        assert(f1 == c1, "f1");
-       assert(fhuge > fhuge_1, "fhuge");
+       assert(fhuge == fhuge_1, "fhuge");      // float64 can't distinguish fhuge, fhuge_1.
        assert(fhuge_1 + 1 == fhuge, "fhuge 1");
        assert(fhuge + fm1 +1  == fhuge, "fm1");
        assert(f3div2 == 1.5, "3./2.");
index 2f1b202258b73512c72644a18bf8b0eb3d9988f5..23dab0a9c436a12253e672d610e857d40767521e 100644 (file)
@@ -25,7 +25,7 @@ var bad5 = "a" + 'a'; // ERROR "literals|incompatible"
 
 var bad6 int = 1.5;    // ERROR "convert"
 var bad7 int = 1e100;  // ERROR "overflow"
-var bad8 float = 1e1000;       // ERROR "overflow"
+var bad8 float32 = 1e200;      // ERROR "overflow"
 
 // but these implicit conversions are okay
 var good1 string = "a";
index dfc7fdd88688aa0bd788c18e3161d2312079d3d7..b2f44429c4a3327e478a0a45c40103ad89051364 100644 (file)
@@ -80,7 +80,7 @@ func main() {
        E(f.s("\t20.8e\t|").wp(20,8).e(1.2345e3).s("|"), "\t20.8e\t|      1.23450000e+03|");
        E(f.s("\t20f\t|").w(20).f64(1.23456789e3).s("|"), "\t20f\t|         1234.567890|");
        E(f.s("\t20f\t|").w(20).f64(1.23456789e-3).s("|"), "\t20f\t|            0.001235|");
-       E(f.s("\t20f\t|").w(20).f64(12345678901.23456789).s("|"), "\t20f\t|  12345678901.234570|");
+       E(f.s("\t20f\t|").w(20).f64(12345678901.23456789).s("|"), "\t20f\t|  12345678901.234568|");
        E(f.s("\t-20f\t|").w(-20).f64(1.23456789e3).s("|"), "\t-20f\t|1234.567890         |");
        E(f.s("\t20.8f\t|").wp(20,8).f64(1.23456789e3).s("|"), "\t20.8f\t|       1234.56789000|");
        E(f.s("\t20.8f\t|").wp(20,8).f64(1.23456789e-3).s("|"), "\t20.8f\t|          0.00123457|");
index ffc7f41ffae4bc9edd041c259e7df79f396e7b90..ec5f8e3183f1fb165c95783fb19a2f5b04f744dd 100644 (file)
@@ -11,11 +11,10 @@ errchk: ./convlit.go: unmatched error messages:
 ==================================================
 ./convlit.go:8: cannot convert non-integer constant to int
 ./convlit.go:11: overflow converting constant to int
-./convlit.go:12: overflow converting constant to float
+./convlit.go:12: overflow in float constant
 ./convlit.go:8: cannot convert non-integer constant to int
 ./convlit.go:9: cannot convert non-integer constant to int
 ./convlit.go:11: overflow converting constant to int
-./convlit.go:12: overflow converting constant to float
 ==================================================
 
 =========== ./helloworld.go
@@ -37,6 +36,9 @@ Faulting address: 0x0
 pc: xxx
 
 
+=========== ./method2.go
+BUG: errchk: command succeeded unexpectedly:  6g ./method2.go
+
 =========== ./peano.go
 0! = 1
 1! = 1
@@ -88,6 +90,9 @@ BUG should compile
 =========== bugs/bug041.go
 BUG: compilation succeeds incorrectly
 
+=========== bugs/bug046.go
+BUG: errchk: command succeeded unexpectedly:  6g bugs/bug046.go
+
 =========== bugs/bug064.go
 bugs/bug064.go:15: illegal types for operand: CALL
        int
@@ -115,6 +120,9 @@ bugs/bug098.go:10: illegal types for operand: AS
        **M
 BUG should compile
 
+=========== bugs/bug104.go
+BUG: errchk: command succeeded unexpectedly:  6g bugs/bug104.go
+
 =========== bugs/bug105.go
 bugs/bug105.go:8: P: undefined
 bugs/bug105.go:9: illegal types for operand: RETURN
@@ -142,13 +150,12 @@ panic on line 85 PC=xxx
 BUG: should not fail
 
 =========== bugs/bug120.go
-Bad float64 const: 456.7 want 456.7 got 456.70000000000005
-Bad float64 const: 100000000000000008388608 want 1.0000000000000001e+23 got 2.0037642052907827e+17
 Bad float64 const: 1e23+8.388608e6 want 1.0000000000000001e+23 got 1e+23
-bug120
-
-panic on line 139 PC=xxx
-BUG: bug120
+       want exact: 100000000000000008388608
+       got exact:  99999999999999991611392
+Bad float64 const: 1e23+1 want 1.0000000000000001e+23 got 1e+23
+       want exact: 100000000000000008388608
+       got exact:  99999999999999991611392
 
 =========== fixedbugs/bug016.go
 fixedbugs/bug016.go:7: overflow converting constant to uint