diff options
| author | Robert Griesemer <gri@golang.org> | 2015-03-13 17:24:30 -0700 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2015-03-14 00:48:53 +0000 |
| commit | 23fd374bf22aa2eea9c07076061ef8cfbc6cf3d7 (patch) | |
| tree | 13107ece1e2026dd83e99fceea9e0da36054dabb /src/math/big/float.go | |
| parent | b10021644145d7148ced74194b0d668a4428cc15 (diff) | |
| download | go-23fd374bf22aa2eea9c07076061ef8cfbc6cf3d7.tar.xz | |
math/big: wrap Float.Cmp result in struct to prevent wrong use
Float.Cmp used to return a value < 0, 0, or > 0 depending on how
arguments x, y compared against each other. With the possibility
of NaNs, the result was changed into an Accuracy (to include Undef).
Consequently, Float.Cmp results could still be compared for (in-)
equality with 0, but comparing if < 0 or > 0 would provide the
wrong answer w/o any obvious notice by the compiler.
This change wraps Float.Cmp results into a struct and accessors
are used to access the desired result. This prevents incorrect
use.
Change-Id: I34e6a6c1859251ec99b5cf953e82542025ace56f
Reviewed-on: https://go-review.googlesource.com/7526
Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/math/big/float.go')
| -rw-r--r-- | src/math/big/float.go | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/src/math/big/float.go b/src/math/big/float.go index 44691c4783..d716c8ca59 100644 --- a/src/math/big/float.go +++ b/src/math/big/float.go @@ -1446,6 +1446,10 @@ func (z *Float) Quo(x, y *Float) *Float { return z } +type cmpResult struct { + acc Accuracy +} + // Cmp compares x and y and returns: // // Below if x < y @@ -1453,44 +1457,45 @@ func (z *Float) Quo(x, y *Float) *Float { // Above if x > y // Undef if any of x, y is NaN // -func (x *Float) Cmp(y *Float) Accuracy { +func (x *Float) Cmp(y *Float) cmpResult { if debugFloat { x.validate() y.validate() } if x.form == nan || y.form == nan { - return Undef + return cmpResult{Undef} } mx := x.ord() my := y.ord() switch { case mx < my: - return Below + return cmpResult{Below} case mx > my: - return Above + return cmpResult{Above} } // mx == my // only if |mx| == 1 we have to compare the mantissae switch mx { case -1: - return y.ucmp(x) + return cmpResult{y.ucmp(x)} case +1: - return x.ucmp(y) + return cmpResult{x.ucmp(y)} } - return Exact + return cmpResult{Exact} } // The following accessors simplify testing of Cmp results. -func (acc Accuracy) Eql() bool { return acc == Exact } -func (acc Accuracy) Neq() bool { return acc != Exact } -func (acc Accuracy) Lss() bool { return acc == Below } -func (acc Accuracy) Leq() bool { return acc&Above == 0 } -func (acc Accuracy) Gtr() bool { return acc == Above } -func (acc Accuracy) Geq() bool { return acc&Below == 0 } +func (res cmpResult) Acc() Accuracy { return res.acc } +func (res cmpResult) Eql() bool { return res.acc == Exact } +func (res cmpResult) Neq() bool { return res.acc != Exact } +func (res cmpResult) Lss() bool { return res.acc == Below } +func (res cmpResult) Leq() bool { return res.acc&Above == 0 } +func (res cmpResult) Gtr() bool { return res.acc == Above } +func (res cmpResult) Geq() bool { return res.acc&Below == 0 } // ord classifies x and returns: // |
