Source file
src/runtime/float.go
1
2
3
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
18 func isNaN(f float64) (is bool) {
19
20 return f != f
21 }
22
23
24 func isFinite(f float64) bool {
25 return !isNaN(f - f)
26 }
27
28
29 func isInf(f float64) bool {
30 return !isNaN(f) && !isFinite(f)
31 }
32
33
34
35
36
37
38
39 func abs(x float64) float64 {
40 const sign = 1 << 63
41 return float64frombits(float64bits(x) &^ sign)
42 }
43
44
45
46 func copysign(x, y float64) float64 {
47 const sign = 1 << 63
48 return float64frombits(float64bits(x)&^sign | float64bits(y)&sign)
49 }
50
51
52 func float64bits(f float64) uint64 {
53 return *(*uint64)(unsafe.Pointer(&f))
54 }
55
56
57
58 func float64frombits(b uint64) float64 {
59 return *(*float64)(unsafe.Pointer(&b))
60 }
61
62
63
64
65
66
67
68
69
70
71
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
88
89
90
91
92
93
94
95
96
97 func ceil(x float64) float64 {
98 return -floor(-x)
99 }
100
101
102
103
104
105
106
107
108
109
110
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
119 }
120 return 0, f
121 }
122
123 x := float64bits(f)
124 e := uint(x>>float64Shift)&float64Mask - float64Bias
125
126
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