Permalink
Browse files

Add Round method from upcoming std lib

  • Loading branch information...
biilmann committed Nov 23, 2017
1 parent f9feb4b commit 5c2149ac77dab2aa38633fda08cfbbf648b5e445
Showing with 47 additions and 11 deletions.
  1. +47 −11 calculator/calculator.go
View
@@ -283,18 +283,54 @@ func calculateDiscount(amountToDiscount, taxes, percentage, fixed uint64, includ
}
// Nopes - no `round` method in go
// See https://gist.github.com/siddontang/1806573b9a8574989ccb
func rint(x float64) uint64 {
v, frac := math.Modf(x)
if x > 0.0 {
if frac > 0.5 || (frac == 0.5 && uint64(v)%2 != 0) {
v += 1.0
}
} else {
if frac < -0.5 || (frac == -0.5 && uint64(v)%2 != 0) {
v -= 1.0
// See https://github.com/golang/go/blob/master/src/math/floor.go#L58
const (
uvone = 0x3FF0000000000000
mask = 0x7FF
shift = 64 - 11 - 1
bias = 1023
signMask = 1 << 63
fracMask = 1<<shift - 1
)
// Round returns the nearest integer, rounding half away from zero.
//
// Special cases are:
// Round(±0) = ±0
// Round(±Inf) = ±Inf
// Round(NaN) = NaN
func Round(x float64) float64 {
// Round is a faster implementation of:
//
// func Round(x float64) float64 {
// t := Trunc(x)
// if Abs(x-t) >= 0.5 {
// return t + Copysign(1, x)
// }
// return t
// }
bits := math.Float64bits(x)
e := uint(bits>>shift) & mask
if e < bias {
// Round abs(x) < 1 including denormals.
bits &= signMask // +-0
if e == bias-1 {
bits |= uvone // +-1
}
} else if e < bias+shift {
// Round any abs(x) >= 1 containing a fractional component [0,1).
//
// Numbers with larger exponents are returned unchanged since they
// must be either an integer, infinity, or NaN.
const half = 1 << (shift - 1)
e -= bias
bits += half >> e
bits &^= fracMask >> e
}
return math.Float64frombits(bits)
}
return uint64(v)
func rint(x float64) uint64 {
return uint64(Round(x))
}

0 comments on commit 5c2149a

Please sign in to comment.