github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/math/floor.go (about) 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 package math 6 7 // Floor returns the greatest integer value less than or equal to x. 8 // 9 // Special cases are: 10 // Floor(±0) = ±0 11 // Floor(±Inf) = ±Inf 12 // Floor(NaN) = NaN 13 func Floor(x float64) float64 14 15 func floor(x float64) float64 { 16 if x == 0 || IsNaN(x) || IsInf(x, 0) { 17 return x 18 } 19 if x < 0 { 20 d, fract := Modf(-x) 21 if fract != 0.0 { 22 d = d + 1 23 } 24 return -d 25 } 26 d, _ := Modf(x) 27 return d 28 } 29 30 // Ceil returns the least integer value greater than or equal to x. 31 // 32 // Special cases are: 33 // Ceil(±0) = ±0 34 // Ceil(±Inf) = ±Inf 35 // Ceil(NaN) = NaN 36 func Ceil(x float64) float64 37 38 func ceil(x float64) float64 { 39 return -Floor(-x) 40 } 41 42 // Trunc returns the integer value of x. 43 // 44 // Special cases are: 45 // Trunc(±0) = ±0 46 // Trunc(±Inf) = ±Inf 47 // Trunc(NaN) = NaN 48 func Trunc(x float64) float64 49 50 func trunc(x float64) float64 { 51 if x == 0 || IsNaN(x) || IsInf(x, 0) { 52 return x 53 } 54 d, _ := Modf(x) 55 return d 56 } 57 58 // Round returns the nearest integer, rounding half away from zero. 59 // 60 // Special cases are: 61 // Round(±0) = ±0 62 // Round(±Inf) = ±Inf 63 // Round(NaN) = NaN 64 func Round(x float64) float64 { 65 // Round is a faster implementation of: 66 // 67 // func Round(x float64) float64 { 68 // t := Trunc(x) 69 // if Abs(x-t) >= 0.5 { 70 // return t + Copysign(1, x) 71 // } 72 // return t 73 // } 74 bits := Float64bits(x) 75 e := uint(bits>>shift) & mask 76 if e < bias { 77 // Round abs(x) < 1 including denormals. 78 bits &= signMask // +-0 79 if e == bias-1 { 80 bits |= uvone // +-1 81 } 82 } else if e < bias+shift { 83 // Round any abs(x) >= 1 containing a fractional component [0,1). 84 // 85 // Numbers with larger exponents are returned unchanged since they 86 // must be either an integer, infinity, or NaN. 87 const half = 1 << (shift - 1) 88 e -= bias 89 bits += half >> e 90 bits &^= fracMask >> e 91 } 92 return Float64frombits(bits) 93 } 94 95 // RoundToEven returns the nearest integer, rounding ties to even. 96 // 97 // Special cases are: 98 // RoundToEven(±0) = ±0 99 // RoundToEven(±Inf) = ±Inf 100 // RoundToEven(NaN) = NaN 101 func RoundToEven(x float64) float64 { 102 // RoundToEven is a faster implementation of: 103 // 104 // func RoundToEven(x float64) float64 { 105 // t := math.Trunc(x) 106 // odd := math.Remainder(t, 2) != 0 107 // if d := math.Abs(x - t); d > 0.5 || (d == 0.5 && odd) { 108 // return t + math.Copysign(1, x) 109 // } 110 // return t 111 // } 112 bits := Float64bits(x) 113 e := uint(bits>>shift) & mask 114 if e >= bias { 115 // Round abs(x) >= 1. 116 // - Large numbers without fractional components, infinity, and NaN are unchanged. 117 // - Add 0.499.. or 0.5 before truncating depending on whether the truncated 118 // number is even or odd (respectively). 119 const halfMinusULP = (1 << (shift - 1)) - 1 120 e -= bias 121 bits += (halfMinusULP + (bits>>(shift-e))&1) >> e 122 bits &^= fracMask >> e 123 } else if e == bias-1 && bits&fracMask != 0 { 124 // Round 0.5 < abs(x) < 1. 125 bits = bits&signMask | uvone // +-1 126 } else { 127 // Round abs(x) <= 0.5 including denormals. 128 bits &= signMask // +-0 129 } 130 return Float64frombits(bits) 131 }