| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package math |
| |
| // Floor returns the greatest integer value less than or equal to x. |
| // |
| // Special cases are: |
| // Floor(±0) = ±0 |
| // Floor(±Inf) = ±Inf |
| // Floor(NaN) = NaN |
| func Floor(x float64) float64 { |
| if haveArchFloor { |
| return archFloor(x) |
| } |
| return floor(x) |
| } |
| |
| func floor(x float64) float64 { |
| if x == 0 || IsNaN(x) || IsInf(x, 0) { |
| return x |
| } |
| if x < 0 { |
| d, fract := Modf(-x) |
| if fract != 0.0 { |
| d = d + 1 |
| } |
| return -d |
| } |
| d, _ := Modf(x) |
| return d |
| } |
| |
| // Ceil returns the least integer value greater than or equal to x. |
| // |
| // Special cases are: |
| // Ceil(±0) = ±0 |
| // Ceil(±Inf) = ±Inf |
| // Ceil(NaN) = NaN |
| func Ceil(x float64) float64 { |
| if haveArchCeil { |
| return archCeil(x) |
| } |
| return ceil(x) |
| } |
| |
| func ceil(x float64) float64 { |
| return -Floor(-x) |
| } |
| |
| // Trunc returns the integer value of x. |
| // |
| // Special cases are: |
| // Trunc(±0) = ±0 |
| // Trunc(±Inf) = ±Inf |
| // Trunc(NaN) = NaN |
| func Trunc(x float64) float64 { |
| if haveArchTrunc { |
| return archTrunc(x) |
| } |
| return trunc(x) |
| } |
| |
| func trunc(x float64) float64 { |
| if x == 0 || IsNaN(x) || IsInf(x, 0) { |
| return x |
| } |
| d, _ := Modf(x) |
| return d |
| } |
| |
| // Round returns the nearest integer, rounding half away from zero. |
| // |
| // Special cases are: |
| // Round(±0) = ±0 |
| // Round(±Inf) = ±Inf |
| // Round(NaN) = NaN |
| func Round(x float64) float64 { |
| // Round is a faster implementation of: |
| // |
| // func Round(x float64) float64 { |
| // t := Trunc(x) |
| // if Abs(x-t) >= 0.5 { |
| // return t + Copysign(1, x) |
| // } |
| // return t |
| // } |
| bits := Float64bits(x) |
| e := uint(bits>>shift) & mask |
| if e < bias { |
| // Round abs(x) < 1 including denormals. |
| bits &= signMask // +-0 |
| if e == bias-1 { |
| bits |= uvone // +-1 |
| } |
| } else if e < bias+shift { |
| // Round any abs(x) >= 1 containing a fractional component [0,1). |
| // |
| // Numbers with larger exponents are returned unchanged since they |
| // must be either an integer, infinity, or NaN. |
| const half = 1 << (shift - 1) |
| e -= bias |
| bits += half >> e |
| bits &^= fracMask >> e |
| } |
| return Float64frombits(bits) |
| } |
| |
| // RoundToEven returns the nearest integer, rounding ties to even. |
| // |
| // Special cases are: |
| // RoundToEven(±0) = ±0 |
| // RoundToEven(±Inf) = ±Inf |
| // RoundToEven(NaN) = NaN |
| func RoundToEven(x float64) float64 { |
| // RoundToEven is a faster implementation of: |
| // |
| // func RoundToEven(x float64) float64 { |
| // t := math.Trunc(x) |
| // odd := math.Remainder(t, 2) != 0 |
| // if d := math.Abs(x - t); d > 0.5 || (d == 0.5 && odd) { |
| // return t + math.Copysign(1, x) |
| // } |
| // return t |
| // } |
| bits := Float64bits(x) |
| e := uint(bits>>shift) & mask |
| if e >= bias { |
| // Round abs(x) >= 1. |
| // - Large numbers without fractional components, infinity, and NaN are unchanged. |
| // - Add 0.499.. or 0.5 before truncating depending on whether the truncated |
| // number is even or odd (respectively). |
| const halfMinusULP = (1 << (shift - 1)) - 1 |
| e -= bias |
| bits += (halfMinusULP + (bits>>(shift-e))&1) >> e |
| bits &^= fracMask >> e |
| } else if e == bias-1 && bits&fracMask != 0 { |
| // Round 0.5 < abs(x) < 1. |
| bits = bits&signMask | uvone // +-1 |
| } else { |
| // Round abs(x) <= 0.5 including denormals. |
| bits &= signMask // +-0 |
| } |
| return Float64frombits(bits) |
| } |