diff options
author | Robert Griesemer <gri@golang.org> | 2015-02-23 10:05:02 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2015-02-23 18:09:36 +0000 |
commit | 2b0213d569dcfdd3f82fa7c98fd5fea26b6e3038 (patch) | |
tree | 302c7047a3f2899956cdf58d61f41fd4d8f9d32a | |
parent | 828129fdbc2d95ab8d8dfa637e0f7251924c8b8b (diff) | |
download | go-2b0213d569dcfdd3f82fa7c98fd5fea26b6e3038.tar.gz go-2b0213d569dcfdd3f82fa7c98fd5fea26b6e3038.zip |
math/big: incorporated feedback from prior TBR reviews
Change-Id: Ida847365223ef09b4a3846e240b4bb6919cb0fe9
Reviewed-on: https://go-review.googlesource.com/5610
Reviewed-by: Alan Donovan <adonovan@google.com>
-rw-r--r-- | src/math/big/float.go | 58 | ||||
-rw-r--r-- | src/math/big/float_test.go | 2 | ||||
-rw-r--r-- | src/math/big/int.go | 2 | ||||
-rw-r--r-- | src/math/big/natconv.go | 2 |
4 files changed, 36 insertions, 28 deletions
diff --git a/src/math/big/float.go b/src/math/big/float.go index 877379c901..47755f2719 100644 --- a/src/math/big/float.go +++ b/src/math/big/float.go @@ -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() diff --git a/src/math/big/float_test.go b/src/math/big/float_test.go index 17247b1eb2..2789cfb9f3 100644 --- a/src/math/big/float_test.go +++ b/src/math/big/float_test.go @@ -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. diff --git a/src/math/big/int.go b/src/math/big/int.go index 5c1b2cd765..0695d78973 100644 --- a/src/math/big/int.go +++ b/src/math/big/int.go @@ -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. diff --git a/src/math/big/natconv.go b/src/math/big/natconv.go index b5c37731fa..022dcfe38c 100644 --- a/src/math/big/natconv.go +++ b/src/math/big/natconv.go @@ -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. // |