Created
November 22, 2017 13:31
-
-
Save gdm85/44f648cc97bb3bf847f21c87e9d19b2d to your computer and use it in GitHub Desktop.
Round function for Go < 1.10
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"math" | |
) | |
// some constants copied from https://github.com/golang/go/blob/master/src/math/bits.go | |
const ( | |
shift = 64 - 11 - 1 | |
bias = 1023 | |
mask = 0x7FF | |
) | |
// Round returns the nearest integer, rounding half away from zero. | |
// This function is available natively in Go 1.10 | |
// | |
// 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 | |
// } | |
const ( | |
signMask = 1 << 63 | |
fracMask = 1<<shift - 1 | |
half = 1 << (shift - 1) | |
one = bias << shift | |
) | |
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 |= one // +-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. | |
e -= bias | |
bits += half >> e | |
bits &^= fracMask >> e | |
} | |
return math.Float64frombits(bits) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment