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