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