From 25b4be5a55d504eff9fc14263fb1125458cdc9ad Mon Sep 17 00:00:00 2001
From: Austin Clements <aclements@csail.mit.edu>
Date: Fri, 17 Jul 2009 15:09:43 -0700
Subject: [PATCH] Support exponential notation in RatFromString.

R=gri
APPROVED=gri
DELTA=30  (25 added, 0 deleted, 5 changed)
OCL=31796
CL=31799
---
 src/pkg/bignum/bignum.go      | 21 ++++++++++++++++++++-
 src/pkg/bignum/bignum_test.go | 12 +++++++++---
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/src/pkg/bignum/bignum.go b/src/pkg/bignum/bignum.go
index 4fe6d04442..4cd520fbe2 100755
--- a/src/pkg/bignum/bignum.go
+++ b/src/pkg/bignum/bignum.go
@@ -1527,5 +1527,24 @@ func RatFromString(s string, base uint) (*Rational, uint, int) {
 		}
 	}
 
-	return MakeRat(a, b), base, alen + blen;
+	// read exponent, if any
+	var elen int;
+	mlen := alen + blen;
+	if mlen < len(s) {
+		ch := s[mlen];
+		if ch == 'e' || ch == 'E' {
+			var e *Integer;
+			e, base, elen = IntFromString(s[mlen + 1 : len(s)], abase);
+			elen++;
+			assert(base == abase);
+			m := Nat(10).Pow(uint(e.mant.Value()));
+			if e.sign {
+				b = b.Mul(m);
+			} else {
+				a = a.MulNat(m);
+			}
+		}
+	}
+
+	return MakeRat(a, b), base, alen + blen + elen;
 }
diff --git a/src/pkg/bignum/bignum_test.go b/src/pkg/bignum/bignum_test.go
index 4f6f3f6f66..88bdf563ab 100644
--- a/src/pkg/bignum/bignum_test.go
+++ b/src/pkg/bignum/bignum_test.go
@@ -213,9 +213,15 @@ func TestRatConv(t *testing.T) {
 	test(4, slen == 7);
 	rat_eq(5, ratFromString("0.", 0, nil), rat_zero);
 	rat_eq(6, ratFromString("0.001f", 10, nil), bignum.Rat(1, 1000));
-	rat_eq(7, ratFromString("10101.0101", 2, nil), bignum.Rat(0x155, 1<<4));
-	rat_eq(8, ratFromString("-0003.145926", 10, &slen), bignum.Rat(-3145926, 1000000));
-	test(9, slen == 12);
+	rat_eq(7, ratFromString(".1", 0, nil), bignum.Rat(1, 10));
+	rat_eq(8, ratFromString("10101.0101", 2, nil), bignum.Rat(0x155, 1<<4));
+	rat_eq(9, ratFromString("-0003.145926", 10, &slen), bignum.Rat(-3145926, 1000000));
+	test(10, slen == 12);
+	rat_eq(11, ratFromString("1e2", 0, nil), bignum.Rat(100, 1));
+	rat_eq(12, ratFromString("1e-2", 0, nil), bignum.Rat(1, 100));
+	rat_eq(13, ratFromString("1.1e2", 0, nil), bignum.Rat(110, 1));
+	rat_eq(14, ratFromString(".1e2x", 0, &slen), bignum.Rat(10, 1));
+	test(15, slen == 4);
 }
 
 
-- 
2.30.9