round.go (1458B)
1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // According to https://github.com/golang/go/issues/20100, the Go stdlib will 6 // include math.Round beginning with Go 1.10. 7 // 8 // The following implementation was taken from https://golang.org/cl/43652. 9 10 package math 11 12 import "math" 13 14 const ( 15 mask = 0x7FF 16 shift = 64 - 11 - 1 17 bias = 1023 18 ) 19 20 // Round returns the nearest integer, rounding half away from zero. 21 // 22 // Special cases are: 23 // Round(±0) = ±0 24 // Round(±Inf) = ±Inf 25 // Round(NaN) = NaN 26 func _round(x float64) float64 { 27 // Round is a faster implementation of: 28 // 29 // func Round(x float64) float64 { 30 // t := Trunc(x) 31 // if Abs(x-t) >= 0.5 { 32 // return t + Copysign(1, x) 33 // } 34 // return t 35 // } 36 const ( 37 signMask = 1 << 63 38 fracMask = 1<<shift - 1 39 half = 1 << (shift - 1) 40 one = bias << shift 41 ) 42 43 bits := math.Float64bits(x) 44 e := uint(bits>>shift) & mask 45 if e < bias { 46 // Round abs(x) < 1 including denormals. 47 bits &= signMask // +-0 48 if e == bias-1 { 49 bits |= one // +-1 50 } 51 } else if e < bias+shift { 52 // Round any abs(x) >= 1 containing a fractional component [0,1). 53 // 54 // Numbers with larger exponents are returned unchanged since they 55 // must be either an integer, infinity, or NaN. 56 e -= bias 57 bits += half >> e 58 bits &^= fracMask >> e 59 } 60 return math.Float64frombits(bits) 61 }