]> Cypherpunks repositories - gostls13.git/commitdiff
math/big: incorporated feedback from prior TBR reviews
authorRobert Griesemer <gri@golang.org>
Mon, 23 Feb 2015 18:05:02 +0000 (10:05 -0800)
committerRobert Griesemer <gri@golang.org>
Mon, 23 Feb 2015 18:09:36 +0000 (18:09 +0000)
Change-Id: Ida847365223ef09b4a3846e240b4bb6919cb0fe9
Reviewed-on: https://go-review.googlesource.com/5610
Reviewed-by: Alan Donovan <adonovan@google.com>
src/math/big/float.go
src/math/big/float_test.go
src/math/big/int.go
src/math/big/natconv.go

index 877379c901befd8e188f3d2be550541e596195f4..47755f2719296c909981a071ab3eb105323e1ba6 100644 (file)
@@ -39,10 +39,10 @@ const debugFloat = true // enable for debugging
 // and according to its rounding mode, unless specified otherwise. If the
 // result precision is 0 (see below), it is set to the precision of the
 // argument with the largest precision value before any rounding takes
-// place. The rounding mode remains unchanged, thus uninitialized Floats
-// provided as result arguments will "inherit" a reasonble precision from
-// the incoming arguments and their mode is the zero value for RoundingMode
-// (ToNearestEven).
+// place, and the rounding mode remains unchanged. Thus, uninitialized Floats
+// provided as result arguments will have their precision set to a reasonable
+// value determined by the operands and their mode is the zero value for
+// RoundingMode (ToNearestEven).
 //
 // By setting the desired precision to 24 or 53 and using ToNearestEven
 // rounding, Float operations produce the same results as the corresponding
@@ -62,6 +62,9 @@ type Float struct {
        prec uint // TODO(gri) make this a 32bit field
 }
 
+// TODO(gri) provide a couple of Example tests showing typical Float intialization
+// and use.
+
 // Internal representation: The mantissa bits x.mant of a Float x are stored
 // in a nat slice long enough to hold up to x.prec bits; the slice may (but
 // doesn't have to) be shorter if the mantissa contains trailing 0 bits.
@@ -158,7 +161,7 @@ func (z *Float) SetPrec(prec uint) *Float {
 // SetMode sets z's rounding mode to mode and returns an exact z.
 // z remains unchanged otherwise.
 func (z *Float) SetMode(mode RoundingMode) *Float {
-       z.acc = Exact
+       z.acc = Exact // TODO(gri) should we not do this? what's the general rule for setting accuracy?
        z.mode = mode
        return z
 }
@@ -274,23 +277,21 @@ func (z *Float) setExp(e int64) {
 }
 
 // debugging support
-func validate(args ...*Float) {
-       for i, x := range args {
-               const msb = 1 << (_W - 1)
-               m := len(x.mant)
-               if m == 0 {
-                       // 0.0 or Inf
-                       if x.exp != 0 && x.exp != infExp {
-                               panic(fmt.Sprintf("#%d: %empty matissa with invalid exponent %d", i, x.exp))
-                       }
-                       continue
-               }
-               if x.mant[m-1]&msb == 0 {
-                       panic(fmt.Sprintf("#%d: msb not set in last word %#x of %s", i, x.mant[m-1], x.Format('p', 0)))
-               }
-               if x.prec <= 0 {
-                       panic(fmt.Sprintf("#%d: invalid precision %d", i, x.prec))
+func validate(x *Float) {
+       const msb = 1 << (_W - 1)
+       m := len(x.mant)
+       if m == 0 {
+               // 0.0 or Inf
+               if x.exp != 0 && x.exp != infExp {
+                       panic(fmt.Sprintf("%empty matissa with invalid exponent %d", x.exp))
                }
+               return
+       }
+       if x.mant[m-1]&msb == 0 {
+               panic(fmt.Sprintf("msb not set in last word %#x of %s", x.mant[m-1], x.Format('p', 0)))
+       }
+       if x.prec <= 0 {
+               panic(fmt.Sprintf("invalid precision %d", x.prec))
        }
 }
 
@@ -1064,7 +1065,8 @@ func (x *Float) ucmp(y *Float) int {
 // result.
 func (z *Float) Add(x, y *Float) *Float {
        if debugFloat {
-               validate(x, y)
+               validate(x)
+               validate(y)
        }
 
        if z.prec == 0 {
@@ -1104,7 +1106,8 @@ func (z *Float) Add(x, y *Float) *Float {
 // Precision, rounding, and accuracy reporting are as for Add.
 func (z *Float) Sub(x, y *Float) *Float {
        if debugFloat {
-               validate(x, y)
+               validate(x)
+               validate(y)
        }
 
        if z.prec == 0 {
@@ -1143,7 +1146,8 @@ func (z *Float) Sub(x, y *Float) *Float {
 // Precision, rounding, and accuracy reporting are as for Add.
 func (z *Float) Mul(x, y *Float) *Float {
        if debugFloat {
-               validate(x, y)
+               validate(x)
+               validate(y)
        }
 
        if z.prec == 0 {
@@ -1171,7 +1175,8 @@ func (z *Float) Mul(x, y *Float) *Float {
 // Precision, rounding, and accuracy reporting are as for Add.
 func (z *Float) Quo(x, y *Float) *Float {
        if debugFloat {
-               validate(x, y)
+               validate(x)
+               validate(y)
        }
 
        if z.prec == 0 {
@@ -1251,7 +1256,8 @@ func (z *Float) Rsh(x *Float, s uint) *Float {
 // Infinities with matching sign are equal.
 func (x *Float) Cmp(y *Float) int {
        if debugFloat {
-               validate(x, y)
+               validate(x)
+               validate(y)
        }
 
        mx := x.ord()
index 17247b1eb2f1f463a81f751425a631fa1efffcf2..2789cfb9f3e0959ae4d4204e0ce2e1916dc6c273 100644 (file)
@@ -1077,6 +1077,8 @@ func TestFloatQuoSmoke(t *testing.T) {
        }
 }
 
+// TODO(gri) Add tests that check correctness in the presence of aliasing.
+
 // For rounding modes ToNegativeInf and ToPositiveInf, rounding is affected
 // by the sign of the value to be rounded. Test that rounding happens after
 // the sign of a result has been set.
index 5c1b2cd7653fa55a21eddbd7bc68d4cdd965919a..0695d78973728dcf8d66dfff85c667de4765108c 100644 (file)
@@ -361,7 +361,7 @@ func (x *Int) Uint64() uint64 {
 // and returns z and a boolean indicating success. If SetString fails,
 // the value of z is undefined but the returned value is nil.
 //
-// The base argument must be 0 or a value from 2 through MaxBase. If the base
+// The base argument must be 0 or a value between 2 and MaxBase. If the base
 // is 0, the string prefix determines the actual conversion base. A prefix of
 // ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
 // ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
index b5c37731fadf59d2be2cea454b34d5c3db6c19f1..022dcfe38c8d363326a9acef69ff5c7089664adb 100644 (file)
@@ -60,7 +60,7 @@ func pow(x Word, n int) (p Word) {
 //     digit    = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
 //
 // Unless fracOk is set, the base argument must be 0 or a value between
-// 2 through MaxBase. If fracOk is set, the base argument must be one of
+// 2 and MaxBase. If fracOk is set, the base argument must be one of
 // 0, 2, 10, or 16. Providing an invalid base argument leads to a run-
 // time panic.
 //