aboutsummaryrefslogtreecommitdiff
path: root/src/math/big/float.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2015-03-13 17:24:30 -0700
committerRobert Griesemer <gri@golang.org>2015-03-14 00:48:53 +0000
commit23fd374bf22aa2eea9c07076061ef8cfbc6cf3d7 (patch)
tree13107ece1e2026dd83e99fceea9e0da36054dabb /src/math/big/float.go
parentb10021644145d7148ced74194b0d668a4428cc15 (diff)
downloadgo-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.go31
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:
//