Source file
src/runtime/float.go
1 // Copyright 2017 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 runtime
6
7 import "unsafe"
8
9 const (
10 float64Mask = 0x7FF
11 float64Shift = 64 - 11 - 1
12 float64Bias = 1023
13 )
14
15 var inf = float64frombits(0x7FF0000000000000)
16
17 // isNaN reports whether f is an IEEE 754 “not-a-number” value.
18 func isNaN(f float64) (is bool) {
19 // IEEE 754 says that only NaNs satisfy f != f.
20 return f != f
21 }
22
23 // isFinite reports whether f is neither NaN nor an infinity.
24 func isFinite(f float64) bool {
25 return !isNaN(f - f)
26 }
27
28 // isInf reports whether f is an infinity.
29 func isInf(f float64) bool {
30 return !isNaN(f) && !isFinite(f)
31 }
32
33 // abs returns the absolute value of x.
34 //
35 // Special cases are:
36 //
37 // abs(±Inf) = +Inf
38 // abs(NaN) = NaN
39 func abs(x float64) float64 {
40 const sign = 1 << 63
41 return float64frombits(float64bits(x) &^ sign)
42 }
43
44 // copysign returns a value with the magnitude
45 // of x and the sign of y.
46 func copysign(x, y float64) float64 {
47 const sign = 1 << 63
48 return float64frombits(float64bits(x)&^sign | float64bits(y)&sign)
49 }
50
51 // float64bits returns the IEEE 754 binary representation of f.
52 func float64bits(f float64) uint64 {
53 return *(*uint64)(unsafe.Pointer(&f))
54 }
55
56 // float64frombits returns the floating point number corresponding
57 // the IEEE 754 binary representation b.
58 func float64frombits(b uint64) float64 {
59 return *(*float64)(unsafe.Pointer(&b))
60 }
61
62 // floor returns the greatest integer value less than or equal to x.
63 //
64 // Special cases are:
65 //
66 // floor(±0) = ±0
67 // floor(±Inf) = ±Inf
68 // floor(NaN) = NaN
69 //
70 // N.B. Portable floor copied from math. math also has optimized arch-specific
71 // implementations.
72 func floor(x float64) float64 {
73 if x == 0 || isNaN(x) || isInf(x) {
74 return x
75 }
76 if x < 0 {
77 d, fract := modf(-x)
78 if fract != 0.0 {
79 d = d + 1
80 }
81 return -d
82 }
83 d, _ := modf(x)
84 return d
85 }
86
87 // ceil returns the least integer value greater than or equal to x.
88 //
89 // Special cases are:
90 //
91 // Ceil(±0) = ±0
92 // Ceil(±Inf) = ±Inf
93 // Ceil(NaN) = NaN
94 //
95 // N.B. Portable ceil copied from math. math also has optimized arch-specific
96 // implementations.
97 func ceil(x float64) float64 {
98 return -floor(-x)
99 }
100
101 // modf returns integer and fractional floating-point numbers
102 // that sum to f. Both values have the same sign as f.
103 //
104 // Special cases are:
105 //
106 // Modf(±Inf) = ±Inf, NaN
107 // Modf(NaN) = NaN, NaN
108 //
109 // N.B. Portable modf copied from math. math also has optimized arch-specific
110 // implementations.
111 func modf(f float64) (int float64, frac float64) {
112 if f < 1 {
113 switch {
114 case f < 0:
115 int, frac = modf(-f)
116 return -int, -frac
117 case f == 0:
118 return f, f // Return -0, -0 when f == -0
119 }
120 return 0, f
121 }
122
123 x := float64bits(f)
124 e := uint(x>>float64Shift)&float64Mask - float64Bias
125
126 // Keep the top 12+e bits, the integer part; clear the rest.
127 if e < 64-12 {
128 x &^= 1<<(64-12-e) - 1
129 }
130 int = float64frombits(x)
131 frac = f - int
132 return
133 }
134
View as plain text