This repository was archived by the owner on May 6, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfloat32.go
229 lines (185 loc) · 7.4 KB
/
float32.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
package operator
// Code generated by (tawesoft.co.uk/go/operator) template-numbers.py: DO NOT EDIT.
import "math"
// Some overflow checks with reference to stackoverflow.com/a/1514309/5654201
type float32Unary struct {
Identity func(float32) float32
Abs func(float32) float32
Negation func(float32) float32
Zero func(float32) bool
NonZero func(float32) bool
Positive func(float32) bool
Negative func(float32) bool
}
type float32UnaryChecked struct {
Abs func(float32) (float32, error)
Negation func(float32) (float32, error)
}
type float32Binary struct {
Add func(float32, float32) float32
Sub func(float32, float32) float32
Mul func(float32, float32) float32
Div func(float32, float32) float32
Mod func(float32, float32) float32
Eq func(float32, float32) bool
Neq func(float32, float32) bool
Lt func(float32, float32) bool
Lte func(float32, float32) bool
Gt func(float32, float32) bool
Gte func(float32, float32) bool
}
type float32BinaryChecked struct {
Add func(float32, float32) (float32, error)
Sub func(float32, float32) (float32, error)
Mul func(float32, float32) (float32, error)
Div func(float32, float32) (float32, error)
}
type float32Nary struct {
Add func(... float32) float32
Sub func(... float32) float32
Mul func(... float32) float32
}
type float32NaryChecked struct {
Add func(... float32) (float32, error)
Sub func(... float32) (float32, error)
Mul func(... float32) (float32, error)
}
// Float32 implements operations on one (unary), two (binary), or many (nary) arguments of type float32.
var Float32 = struct {
Unary float32Unary
Binary float32Binary
Nary float32Nary
Reduce func(operatorIdentity float32, operator func(float32, float32) float32, elements ... float32) float32
}{
Unary: float32Unary{
Identity: func(a float32) float32 { return a },
Abs: float32UnaryAbs,
Negation: func(a float32) float32 { return -a },
Zero: func(a float32) bool { return a == 0 },
NonZero: func(a float32) bool { return a != 0 },
Positive: float32UnaryPositive,
Negative: float32UnaryNegative,
},
Binary: float32Binary{
Add: func(a float32, b float32) float32 { return a + b },
Sub: func(a float32, b float32) float32 { return a - b },
Mul: func(a float32, b float32) float32 { return a * b },
Div: func(a float32, b float32) float32 { return a / b },
Eq: func(a float32, b float32) bool { return a == b },
Neq: func(a float32, b float32) bool { return a != b },
Lt: func(a float32, b float32) bool { return a < b },
Lte: func(a float32, b float32) bool { return a <= b },
Gt: func(a float32, b float32) bool { return a > b },
Gte: func(a float32, b float32) bool { return a >= b },
},
Nary: float32Nary{
Add: float32NaryAdd,
Mul: float32NaryMul,
},
Reduce: float32Reduce,
}
// Float32Checked implements operations on one (unary), two (binary), or many (nary) arguments of type float32, returning an
// error in cases such as overflow or an undefined operation.
var Float32Checked = struct {
Unary float32UnaryChecked
Binary float32BinaryChecked
Nary float32NaryChecked
Reduce func(operatorIdentity float32, operator func(float32, float32) (float32, error), elements ... float32) (float32, error)
}{
Unary: float32UnaryChecked{
Abs: float32UnaryCheckedAbs,
Negation: float32UnaryCheckedNegation,
},
Binary: float32BinaryChecked{
Add: float32BinaryCheckedAdd,
Sub: float32BinaryCheckedSub,
Mul: float32BinaryCheckedMul,
Div: float32BinaryCheckedDiv,
},
Nary: float32NaryChecked{
Add: float32NaryCheckedAdd,
Mul: float32NaryCheckedMul,
},
Reduce: float32CheckedReduce,
}
func float32UnaryPositive(a float32) bool {
return math.Signbit(float64(a)) == false
}
func float32UnaryNegative(a float32) bool {
return math.Signbit(float64(a)) == true
}
func float32UnaryAbs(a float32) float32 {
return float32(math.Abs(float64(a)))
}
// note abs(+/- Inf) = +Inf
func float32UnaryCheckedAbs(a float32) (v float32, err error) {
if math.IsNaN(float64(a)) { return v, ErrorNaN }
return float32(math.Abs(float64(a))), nil
}
func float32UnaryCheckedNegation(a float32) (v float32, err error) {
if math.IsNaN(float64(a)) { return v, ErrorNaN }
return -a, nil
}
func float32BinaryCheckedAdd(a float32, b float32) (v float32, err error) {
if (b > 0) && (a > (maxFloat32 - b)) { return v, ErrorOverflow }
if (b < 0) && (a < (minFloat32 - b)) { return v, ErrorOverflow }
return a + b, nil
}
func float32BinaryCheckedSub(a float32, b float32) (v float32, err error) {
if (b < 0) && (a > (maxFloat32 + b)) { return v, ErrorOverflow }
if (b > 0) && (a < (minFloat32 + b)) { return v, ErrorOverflow }
return a - b, nil
}
func float32BinaryCheckedMul(a float32, b float32) (v float32, err error) {
if (a > (maxFloat32 / b)) { return v, ErrorOverflow }
if (a < (minFloat32 / b)) { return v, ErrorOverflow }
return a * b, nil
}
func float32BinaryCheckedDiv(a float32, b float32) (v float32, err error) {
if math.IsNaN(float64(a)) { return v, ErrorNaN }
if (b == 0) { return v, ErrorUndefined }
return a / b, nil
}
func float32NaryAdd(xs ... float32) (result float32) {
for i := 0; i < len(xs); i++ {
result += xs[i]
}
return result
}
func float32NaryCheckedAdd(xs ... float32) (result float32, err error) {
for i := 0; i < len(xs); i++ {
result, err = float32BinaryCheckedAdd(result, xs[i])
if err != nil { return result, err }
}
return result, nil
}
func float32NaryMul(xs ... float32) (result float32) {
result = 1
for i := 0; i < len(xs); i++ {
result *= xs[i]
}
return result
}
func float32NaryCheckedMul(xs ... float32) (result float32, err error) {
result = 1
for i := 0; i < len(xs); i++ {
result, err = float32BinaryCheckedMul(result, xs[i])
if err != nil { return result, err }
}
return result, nil
}
func float32Reduce(operatorIdentity float32, operator func(float32, float32) float32, elements ... float32) (result float32) {
result = operatorIdentity
for i := 0; i < len(elements); i++ {
result = operator(result, elements[i])
}
return result
}
func float32CheckedReduce(operatorIdentity float32, operator func(float32, float32) (float32, error), elements ... float32) (result float32, err error) {
result = operatorIdentity
for i := 0; i < len(elements); i++ {
result, err = operator(result, elements[i])
if err != nil { return result, err }
}
return result, err
}