summaryrefslogtreecommitdiffstats
path: root/kube2msb/src/kube2msb/vendor/gopkg.in/inf.v0/rounder.go
diff options
context:
space:
mode:
Diffstat (limited to 'kube2msb/src/kube2msb/vendor/gopkg.in/inf.v0/rounder.go')
-rw-r--r--kube2msb/src/kube2msb/vendor/gopkg.in/inf.v0/rounder.go145
1 files changed, 145 insertions, 0 deletions
diff --git a/kube2msb/src/kube2msb/vendor/gopkg.in/inf.v0/rounder.go b/kube2msb/src/kube2msb/vendor/gopkg.in/inf.v0/rounder.go
new file mode 100644
index 0000000..3a97ef5
--- /dev/null
+++ b/kube2msb/src/kube2msb/vendor/gopkg.in/inf.v0/rounder.go
@@ -0,0 +1,145 @@
+package inf
+
+import (
+ "math/big"
+)
+
+// Rounder represents a method for rounding the (possibly infinite decimal)
+// result of a division to a finite Dec. It is used by Dec.Round() and
+// Dec.Quo().
+//
+// See the Example for results of using each Rounder with some sample values.
+//
+type Rounder rounder
+
+// See http://speleotrove.com/decimal/damodel.html#refround for more detailed
+// definitions of these rounding modes.
+var (
+ RoundDown Rounder // towards 0
+ RoundUp Rounder // away from 0
+ RoundFloor Rounder // towards -infinity
+ RoundCeil Rounder // towards +infinity
+ RoundHalfDown Rounder // to nearest; towards 0 if same distance
+ RoundHalfUp Rounder // to nearest; away from 0 if same distance
+ RoundHalfEven Rounder // to nearest; even last digit if same distance
+)
+
+// RoundExact is to be used in the case when rounding is not necessary.
+// When used with Quo or Round, it returns the result verbatim when it can be
+// expressed exactly with the given precision, and it returns nil otherwise.
+// QuoExact is a shorthand for using Quo with RoundExact.
+var RoundExact Rounder
+
+type rounder interface {
+
+ // When UseRemainder() returns true, the Round() method is passed the
+ // remainder of the division, expressed as the numerator and denominator of
+ // a rational.
+ UseRemainder() bool
+
+ // Round sets the rounded value of a quotient to z, and returns z.
+ // quo is rounded down (truncated towards zero) to the scale obtained from
+ // the Scaler in Quo().
+ //
+ // When the remainder is not used, remNum and remDen are nil.
+ // When used, the remainder is normalized between -1 and 1; that is:
+ //
+ // -|remDen| < remNum < |remDen|
+ //
+ // remDen has the same sign as y, and remNum is zero or has the same sign
+ // as x.
+ Round(z, quo *Dec, remNum, remDen *big.Int) *Dec
+}
+
+type rndr struct {
+ useRem bool
+ round func(z, quo *Dec, remNum, remDen *big.Int) *Dec
+}
+
+func (r rndr) UseRemainder() bool {
+ return r.useRem
+}
+
+func (r rndr) Round(z, quo *Dec, remNum, remDen *big.Int) *Dec {
+ return r.round(z, quo, remNum, remDen)
+}
+
+var intSign = []*big.Int{big.NewInt(-1), big.NewInt(0), big.NewInt(1)}
+
+func roundHalf(f func(c int, odd uint) (roundUp bool)) func(z, q *Dec, rA, rB *big.Int) *Dec {
+ return func(z, q *Dec, rA, rB *big.Int) *Dec {
+ z.Set(q)
+ brA, brB := rA.BitLen(), rB.BitLen()
+ if brA < brB-1 {
+ // brA < brB-1 => |rA| < |rB/2|
+ return z
+ }
+ roundUp := false
+ srA, srB := rA.Sign(), rB.Sign()
+ s := srA * srB
+ if brA == brB-1 {
+ rA2 := new(big.Int).Lsh(rA, 1)
+ if s < 0 {
+ rA2.Neg(rA2)
+ }
+ roundUp = f(rA2.Cmp(rB)*srB, z.UnscaledBig().Bit(0))
+ } else {
+ // brA > brB-1 => |rA| > |rB/2|
+ roundUp = true
+ }
+ if roundUp {
+ z.UnscaledBig().Add(z.UnscaledBig(), intSign[s+1])
+ }
+ return z
+ }
+}
+
+func init() {
+ RoundExact = rndr{true,
+ func(z, q *Dec, rA, rB *big.Int) *Dec {
+ if rA.Sign() != 0 {
+ return nil
+ }
+ return z.Set(q)
+ }}
+ RoundDown = rndr{false,
+ func(z, q *Dec, rA, rB *big.Int) *Dec {
+ return z.Set(q)
+ }}
+ RoundUp = rndr{true,
+ func(z, q *Dec, rA, rB *big.Int) *Dec {
+ z.Set(q)
+ if rA.Sign() != 0 {
+ z.UnscaledBig().Add(z.UnscaledBig(), intSign[rA.Sign()*rB.Sign()+1])
+ }
+ return z
+ }}
+ RoundFloor = rndr{true,
+ func(z, q *Dec, rA, rB *big.Int) *Dec {
+ z.Set(q)
+ if rA.Sign()*rB.Sign() < 0 {
+ z.UnscaledBig().Add(z.UnscaledBig(), intSign[0])
+ }
+ return z
+ }}
+ RoundCeil = rndr{true,
+ func(z, q *Dec, rA, rB *big.Int) *Dec {
+ z.Set(q)
+ if rA.Sign()*rB.Sign() > 0 {
+ z.UnscaledBig().Add(z.UnscaledBig(), intSign[2])
+ }
+ return z
+ }}
+ RoundHalfDown = rndr{true, roundHalf(
+ func(c int, odd uint) bool {
+ return c > 0
+ })}
+ RoundHalfUp = rndr{true, roundHalf(
+ func(c int, odd uint) bool {
+ return c >= 0
+ })}
+ RoundHalfEven = rndr{true, roundHalf(
+ func(c int, odd uint) bool {
+ return c > 0 || c == 0 && odd == 1
+ })}
+}