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