Skip to content

Commit

Permalink
fix the easy parts of bug120
Browse files Browse the repository at this point in the history
R=r,ken
DELTA=66  (52 added, 3 deleted, 11 changed)
OCL=19386
CL=19389
  • Loading branch information
rsc committed Nov 17, 2008
1 parent b7f01f9 commit a1585b6
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/cmd/gc/go.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 14 additions & 3 deletions src/cmd/gc/mparith1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -149,7 +151,7 @@ mpcomfix(Mpint *a)
void
mpmovefixflt(Mpflt *a, Mpint *b)
{
mpmovecflt(a, mpgetfix(b));
mpmovecflt(a, mpgetfixflt(b));
}

void
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
{
Expand Down
11 changes: 11 additions & 0 deletions src/cmd/gc/mparith2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
21 changes: 20 additions & 1 deletion test/bugs/bug120.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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;
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down
2 changes: 1 addition & 1 deletion test/convlit.go
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
2 changes: 1 addition & 1 deletion test/fmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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|");
Expand Down
23 changes: 15 additions & 8 deletions test/golden.out
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit a1585b6

Please sign in to comment.