-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.go
121 lines (98 loc) · 2.6 KB
/
types.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
package maths
import (
"math"
"unsafe"
"golang.org/x/exp/constraints"
)
type Number interface {
constraints.Integer | constraints.Float
}
func MaxValue[T any]() T {
var val T
switch any(val).(type) {
case uint8, uint16, uint32, uint64, uint:
var maxUintVal uint64 = ^uint64(0)
return *(*T)(unsafe.Pointer(&maxUintVal))
case int8, int16, int32, int64, int:
var maxIntVal int64 = math.MaxInt8
size := sizeof[T]()
for i := 1; i < size; i++ {
maxIntVal <<= 8
maxIntVal += 0xFF
}
return *(*T)(unsafe.Pointer(&maxIntVal))
case float32:
var maxFloat32Val float32 = math.MaxFloat32
return *(*T)(unsafe.Pointer(&maxFloat32Val))
case float64:
var maxFloat64Val float64 = math.MaxFloat64
return *(*T)(unsafe.Pointer(&maxFloat64Val))
default:
panic("unsupported type")
}
}
func MinValue[T any]() T {
var val T
switch any(val).(type) {
case uint8, uint16, uint32, uint64, uint:
var minUintVal uint64 = uint64(0)
return *(*T)(unsafe.Pointer(&minUintVal))
case int8, int16, int32, int64, int:
var minIntVal int64 = math.MinInt8
size := sizeof[T]()
for i := 1; i < size; i++ {
minIntVal <<= 8
}
return *(*T)(unsafe.Pointer(&minIntVal))
case float32:
var minFloat32Val float32 = -math.MaxFloat32
return *(*T)(unsafe.Pointer(&minFloat32Val))
case float64:
var minFloat64Val float64 = -math.MaxFloat64
return *(*T)(unsafe.Pointer(&minFloat64Val))
default:
panic("unsupported type")
}
}
func EpsilonValue[T any]() T {
var val T
switch any(val).(type) {
case uint8, uint16, uint32, uint64, uint:
var epsilonUintVal uint64 = 1
return *(*T)(unsafe.Pointer(&epsilonUintVal))
case int8, int16, int32, int64, int:
var epsilonIntVal uint64 = 1
return *(*T)(unsafe.Pointer(&epsilonIntVal))
case float32:
var epsilonFloat32Val float32 = math.SmallestNonzeroFloat32
return *(*T)(unsafe.Pointer(&epsilonFloat32Val))
case float64:
var epsilonFloat64Val float64 = math.SmallestNonzeroFloat64
return *(*T)(unsafe.Pointer(&epsilonFloat64Val))
default:
panic("unsupported type")
}
}
func One[T any]() T {
var val T
switch any(val).(type) {
case uint8, uint16, uint32, uint64, uint:
var oneUintVal uint64 = uint64(1)
return *(*T)(unsafe.Pointer(&oneUintVal))
case int8, int16, int32, int64, int:
var oneIntVal int64 = 1
return *(*T)(unsafe.Pointer(&oneIntVal))
case float32:
var oneFloat32Val float32 = 1
return *(*T)(unsafe.Pointer(&oneFloat32Val))
case float64:
var oneFloat64Val float64 = 1
return *(*T)(unsafe.Pointer(&oneFloat64Val))
default:
panic("unsupported type")
}
}
func sizeof[T any]() int {
var val T
return int(unsafe.Sizeof(val))
}