1
0
mirror of https://github.com/golang/go synced 2024-11-11 20:50:23 -07:00

fix the easy parts of bug120

R=r,ken
DELTA=66  (52 added, 3 deleted, 11 changed)
OCL=19386
CL=19389
This commit is contained in:
Russ Cox 2008-11-17 13:58:45 -08:00
parent b7f01f9f41
commit a1585b676b
8 changed files with 64 additions and 15 deletions

View File

@ -558,6 +558,7 @@ void mprshfixfix(Mpint *a, Mpint *b);
void mpxorfixfix(Mpint *a, Mpint *b); void mpxorfixfix(Mpint *a, Mpint *b);
void mpcomfix(Mpint *a); void mpcomfix(Mpint *a);
vlong mpgetfix(Mpint *a); vlong mpgetfix(Mpint *a);
double mpgetfixflt(Mpint *a);
/* /*
* mparith3.c * mparith3.c

View File

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
#include <u.h>
#include <errno.h>
#include "go.h" #include "go.h"
/// uses arithmetic /// uses arithmetic
@ -149,7 +151,7 @@ mpcomfix(Mpint *a)
void void
mpmovefixflt(Mpflt *a, Mpint *b) mpmovefixflt(Mpflt *a, Mpint *b)
{ {
mpmovecflt(a, mpgetfix(b)); mpmovecflt(a, mpgetfixflt(b));
} }
void void
@ -200,6 +202,15 @@ mpatoflt(Mpflt *a, char *as)
{ {
int dp, c, f, ef, ex, zer; int dp, c, f, ef, ex, zer;
char *s; 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; s = as;
dp = 0; /* digits after decimal point */ dp = 0; /* digits after decimal point */
@ -279,7 +290,7 @@ mpatoflt(Mpflt *a, char *as)
return; return;
bad: bad:
warn("set ovf in mpatof"); warn("set ovf in mpatof: %s", as);
mpmovecflt(a, 0.0); mpmovecflt(a, 0.0);
} }

View File

@ -459,6 +459,17 @@ mpgetfix(Mpint *a)
return v; 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 void
mpmovecfix(Mpint *a, vlong c) mpmovecfix(Mpint *a, vlong c)
{ {

View File

@ -19,8 +19,21 @@ var tests = []Test {
Test{ 456.7, "456.7", "456.7" }, Test{ 456.7, "456.7", "456.7" },
Test{ 1e23+8.5e6, "1e23+8.5e6", "1.0000000000000001e+23" }, Test{ 1e23+8.5e6, "1e23+8.5e6", "1.0000000000000001e+23" },
Test{ 100000000000000008388608, "100000000000000008388608", "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.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() { func main() {
@ -30,6 +43,12 @@ func main() {
v := strconv.ftoa64(t.f, 'g', -1); v := strconv.ftoa64(t.f, 'g', -1);
if v != t.out { if v != t.out {
println("Bad float64 const:", t.in, "want", t.out, "got", v); 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; ok = false;
} }
} }

View File

@ -76,7 +76,7 @@ func ints() {
func floats() { func floats() {
assert(f0 == c0, "f0"); assert(f0 == c0, "f0");
assert(f1 == c1, "f1"); 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_1 + 1 == fhuge, "fhuge 1");
assert(fhuge + fm1 +1 == fhuge, "fm1"); assert(fhuge + fm1 +1 == fhuge, "fm1");
assert(f3div2 == 1.5, "3./2."); assert(f3div2 == 1.5, "3./2.");

View File

@ -25,7 +25,7 @@ var bad5 = "a" + 'a'; // ERROR "literals|incompatible"
var bad6 int = 1.5; // ERROR "convert" var bad6 int = 1.5; // ERROR "convert"
var bad7 int = 1e100; // ERROR "overflow" var bad7 int = 1e100; // ERROR "overflow"
var bad8 float = 1e1000; // ERROR "overflow" var bad8 float32 = 1e200; // ERROR "overflow"
// but these implicit conversions are okay // but these implicit conversions are okay
var good1 string = "a"; var good1 string = "a";

View 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("\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.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(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("\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.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|"); E(f.s("\t20.8f\t|").wp(20,8).f64(1.23456789e-3).s("|"), "\t20.8f\t| 0.00123457|");

View File

@ -11,11 +11,10 @@ errchk: ./convlit.go: unmatched error messages:
================================================== ==================================================
./convlit.go:8: cannot convert non-integer constant to int ./convlit.go:8: cannot convert non-integer constant to int
./convlit.go:11: overflow converting 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:8: cannot convert non-integer constant to int
./convlit.go:9: 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:11: overflow converting constant to int
./convlit.go:12: overflow converting constant to float
================================================== ==================================================
=========== ./helloworld.go =========== ./helloworld.go
@ -37,6 +36,9 @@ Faulting address: 0x0
pc: xxx pc: xxx
=========== ./method2.go
BUG: errchk: command succeeded unexpectedly: 6g ./method2.go
=========== ./peano.go =========== ./peano.go
0! = 1 0! = 1
1! = 1 1! = 1
@ -88,6 +90,9 @@ BUG should compile
=========== bugs/bug041.go =========== bugs/bug041.go
BUG: compilation succeeds incorrectly BUG: compilation succeeds incorrectly
=========== bugs/bug046.go
BUG: errchk: command succeeded unexpectedly: 6g bugs/bug046.go
=========== bugs/bug064.go =========== bugs/bug064.go
bugs/bug064.go:15: illegal types for operand: CALL bugs/bug064.go:15: illegal types for operand: CALL
int int
@ -115,6 +120,9 @@ bugs/bug098.go:10: illegal types for operand: AS
**M **M
BUG should compile BUG should compile
=========== bugs/bug104.go
BUG: errchk: command succeeded unexpectedly: 6g bugs/bug104.go
=========== bugs/bug105.go =========== bugs/bug105.go
bugs/bug105.go:8: P: undefined bugs/bug105.go:8: P: undefined
bugs/bug105.go:9: illegal types for operand: RETURN bugs/bug105.go:9: illegal types for operand: RETURN
@ -142,13 +150,12 @@ panic on line 85 PC=xxx
BUG: should not fail BUG: should not fail
=========== bugs/bug120.go =========== 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 Bad float64 const: 1e23+8.388608e6 want 1.0000000000000001e+23 got 1e+23
bug120 want exact: 100000000000000008388608
got exact: 99999999999999991611392
panic on line 139 PC=xxx Bad float64 const: 1e23+1 want 1.0000000000000001e+23 got 1e+23
BUG: bug120 want exact: 100000000000000008388608
got exact: 99999999999999991611392
=========== fixedbugs/bug016.go =========== fixedbugs/bug016.go
fixedbugs/bug016.go:7: overflow converting constant to uint fixedbugs/bug016.go:7: overflow converting constant to uint