]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: check exponent overflow and underflow in mparith
authorJan Ziak <0xe2.0x9a.0x9b@gmail.com>
Wed, 19 Mar 2014 04:48:00 +0000 (05:48 +0100)
committerJan Ziak <0xe2.0x9a.0x9b@gmail.com>
Wed, 19 Mar 2014 04:48:00 +0000 (05:48 +0100)
A too large float constant is an error.
A too small float constant is rounded to zero.

Fixes #7419
Update #6902

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/76730046

src/cmd/gc/go.h
src/cmd/gc/mparith1.c
src/cmd/gc/mparith3.c
test/fixedbugs/issue7419.go [new file with mode: 0644]

index 151032eb905ffe75dec9ae2f28c23ee77cbecdea..36d51675945cd92933970659c6cd0b088a8df5c2 100644 (file)
@@ -1255,6 +1255,7 @@ void      mpmovecflt(Mpflt *a, double c);
 void   mpmulfltflt(Mpflt *a, Mpflt *b);
 void   mpnegflt(Mpflt *a);
 void   mpnorm(Mpflt *a);
+void   mpsetexp(Mpflt *a, int exp);
 int    mptestflt(Mpflt *a);
 int    sigfig(Mpflt *a);
 
index 41412c416d0fcbe901ac35b7a19be6d7cd0a76d7..19310a7c8c2701ea9beb03165af4472d634fa58e 100644 (file)
@@ -416,7 +416,7 @@ mpatoflt(Mpflt *a, char *as)
        if(eb) {
                if(dp)
                        goto bad;
-               a->exp += ex;
+               mpsetexp(a, a->exp+ex);
                goto out;
        }
 
@@ -427,8 +427,13 @@ mpatoflt(Mpflt *a, char *as)
                        mppow10flt(&b, ex-dp);
                        mpmulfltflt(a, &b);
                } else {
-                       mppow10flt(&b, dp-ex);
-                       mpdivfltflt(a, &b);
+                       if((short)(dp-ex) != dp-ex) {
+                               mpmovecflt(a, 0.0);
+                       }
+                       else {
+                               mppow10flt(&b, dp-ex);
+                               mpdivfltflt(a, &b);
+                       }
                }
        }
 
index f8344c9b4e51c51311714cc93bf7b95225437062..da5372cd8334a1edc52d8b1075d1033fcf6b8048 100644 (file)
@@ -22,6 +22,27 @@ sigfig(Mpflt *a)
        return i+1;
 }
 
+/*
+ * sets the exponent.
+ * a too large exponent is an error.
+ * a too small exponent rounds the number to zero.
+ */
+void
+mpsetexp(Mpflt *a, int exp) {
+       if((short)exp != exp) {
+               if(exp > 0) {
+                       yyerror("float constant is too large");
+                       a->exp = 0x7fff;
+               }
+               else {
+                       mpmovecflt(a, 0);
+               }
+       }
+       else {
+               a->exp = exp;
+       }
+}
+
 /*
  * shifts the leading non-zero
  * word of the number to Mpnorm
@@ -60,7 +81,7 @@ mpnorm(Mpflt *a)
        }
 
        mpshiftfix(&a->val, s);
-       a->exp -= s;
+       mpsetexp(a, a->exp-s);
 }
 
 /// implements float arihmetic
@@ -95,7 +116,7 @@ mpaddfltflt(Mpflt *a, Mpflt *b)
        if(s < 0) {
                // b is larger, shift a right
                mpshiftfix(&a->val, s);
-               a->exp -= s;
+               mpsetexp(a, a->exp-s);
                mpaddfixfix(&a->val, &b->val, 0);
                goto out;
        }
@@ -131,7 +152,7 @@ mpmulfltflt(Mpflt *a, Mpflt *b)
        }
 
        mpmulfract(&a->val, &b->val);
-       a->exp = (a->exp + b->exp) + Mpscale*Mpprec - Mpscale - 1;
+       mpsetexp(a, (a->exp + b->exp) + Mpscale*Mpprec - Mpscale - 1);
 
        mpnorm(a);
        if(Mpdebug)
@@ -171,7 +192,7 @@ mpdivfltflt(Mpflt *a, Mpflt *b)
 
        // divide
        mpdivfract(&a->val, &c.val);
-       a->exp = (a->exp-c.exp) - Mpscale*(Mpprec-1) + 1;
+       mpsetexp(a, (a->exp-c.exp) - Mpscale*(Mpprec-1) + 1);
 
        mpnorm(a);
        if(Mpdebug)
@@ -199,7 +220,10 @@ mpgetflt(Mpflt *a)
 
        while((a->val.a[Mpnorm-1] & Mpsign) == 0) {
                mpshiftfix(&a->val, 1);
-               a->exp -= 1;
+               mpsetexp(a, a->exp-1);  // can set 'a' to zero
+               s = sigfig(a);
+               if(s == 0)
+                       return 0;
        }
 
        // the magic numbers (64, 63, 53, 10, -1074) are
diff --git a/test/fixedbugs/issue7419.go b/test/fixedbugs/issue7419.go
new file mode 100644 (file)
index 0000000..39b454c
--- /dev/null
@@ -0,0 +1,25 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 7419: odd behavior for float constants underflowing to 0
+
+package main
+
+import (
+       "os"
+)
+
+var x = 1e-779137
+var y = 1e-779138
+
+func main() {
+       if x != 0 {
+               os.Exit(1)
+       }
+       if y != 0 {
+               os.Exit(2)
+       }
+}