blob: 9115968c74a12ccda29b7ba7eda5098fdec1bd80 [file] [log] [blame]
Ian Lance Taylordbc0c7e2018-01-05 13:26:30 -08001// Copyright 2009 The Go Authors. All rights reserved.
Ian Lance Taylor0ef89c42010-01-29 13:33:36 -08002// 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
Ian Lance Taylor0ef89c42010-01-29 13:33:36 -08007// Floor returns the greatest integer value less than or equal to x.
Ian Lance Taylorfb6b68d2010-02-19 21:28:16 -08008//
9// Special cases are:
Ian Lance Taylor0f0f9c12012-01-11 17:09:03 -080010// Floor(±0) = ±0
Ian Lance Taylorce5916e2011-12-13 11:14:08 -080011// Floor(±Inf) = ±Inf
Ian Lance Taylorfb6b68d2010-02-19 21:28:16 -080012// Floor(NaN) = NaN
Ian Lance Tayloradccafd2012-02-07 11:19:23 -080013
14//extern floor
15func libc_floor(float64) float64
16
Ian Lance Taylor0ef89c42010-01-29 13:33:36 -080017func Floor(x float64) float64 {
Ian Lance Taylor0f0f9c12012-01-11 17:09:03 -080018 return libc_floor(x)
19}
20
21func floor(x float64) float64 {
Ian Lance Taylor8cf10fb2012-02-09 00:06:37 -080022 if x == 0 || IsNaN(x) || IsInf(x, 0) {
Ian Lance Taylorfb6b68d2010-02-19 21:28:16 -080023 return x
24 }
Ian Lance Taylor0ef89c42010-01-29 13:33:36 -080025 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.
Ian Lance Taylorfb6b68d2010-02-19 21:28:16 -080037//
38// Special cases are:
Ian Lance Taylor0f0f9c12012-01-11 17:09:03 -080039// Ceil(±0) = ±0
Ian Lance Taylorce5916e2011-12-13 11:14:08 -080040// Ceil(±Inf) = ±Inf
Ian Lance Taylorfb6b68d2010-02-19 21:28:16 -080041// Ceil(NaN) = NaN
Ian Lance Tayloradccafd2012-02-07 11:19:23 -080042
43//extern ceil
44func libc_ceil(float64) float64
45
Ian Lance Taylor0f0f9c12012-01-11 17:09:03 -080046func Ceil(x float64) float64 {
47 return libc_ceil(x)
48}
49
50func ceil(x float64) float64 {
51 return -Floor(-x)
52}
Ian Lance Taylorfb6b68d2010-02-19 21:28:16 -080053
54// Trunc returns the integer value of x.
55//
56// Special cases are:
Ian Lance Taylor0f0f9c12012-01-11 17:09:03 -080057// Trunc(±0) = ±0
Ian Lance Taylorce5916e2011-12-13 11:14:08 -080058// Trunc(±Inf) = ±Inf
Ian Lance Taylorfb6b68d2010-02-19 21:28:16 -080059// Trunc(NaN) = NaN
Ian Lance Tayloradccafd2012-02-07 11:19:23 -080060
Ian Lance Taylorfb6b68d2010-02-19 21:28:16 -080061func Trunc(x float64) float64 {
Ian Lance Taylore76b03d2012-02-15 23:15:01 -080062 return trunc(x)
Ian Lance Taylor0f0f9c12012-01-11 17:09:03 -080063}
64
65func trunc(x float64) float64 {
Ian Lance Taylor8cf10fb2012-02-09 00:06:37 -080066 if x == 0 || IsNaN(x) || IsInf(x, 0) {
Ian Lance Taylorfb6b68d2010-02-19 21:28:16 -080067 return x
68 }
69 d, _ := Modf(x)
70 return d
71}
Ian Lance Taylordbc0c7e2018-01-05 13:26:30 -080072
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
79func 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
116func 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}