-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconversion.go
150 lines (128 loc) · 3.29 KB
/
conversion.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
// Package conversion TODO(kkweon): Write description
package conversion
import (
"github.com/deepbaksu/conversion/internal"
"encoding/binary"
"errors"
"math"
)
type Endian int
const (
BigEndian Endian = iota
LittleEndian
)
type Option struct {
Endian Endian
}
// IntToFloat32 converts int to float32
func IntToFloat32(x int) float32 {
return float32(x)
}
// Float32ToBytes converts float32 to []byte with length 4
func Float32ToBytes(x float32, o *Option) []byte {
b := make([]byte, 4)
ux := math.Float32bits(x)
if o == nil || o.Endian == BigEndian {
binary.BigEndian.PutUint32(b, ux)
} else {
binary.LittleEndian.PutUint32(b, ux)
}
return b
}
// BytesToFloat32 converts []byte to float32
// length of []byte should be 4 or bigger
func BytesToFloat32(x []byte, o *Option) (float32, error) {
var fx float32
if len(x) < 4 {
return fx, errors.New("length of []byte should be 4 or bigger")
}
var ux uint32
if o == nil || o.Endian == BigEndian {
ux = binary.BigEndian.Uint32(x)
} else {
ux = binary.LittleEndian.Uint32(x)
}
return math.Float32frombits(ux), nil
}
// Float64ToBytes converts float64 to []byte with length 8
func Float64ToBytes(x float64, o *Option) []byte {
b := make([]byte, 8)
ux := math.Float64bits(x)
if o == nil || o.Endian == BigEndian {
binary.BigEndian.PutUint64(b, ux)
} else {
binary.LittleEndian.PutUint64(b, ux)
}
return b
}
// BytesToFloat64 converts []byte to float64
// length of []byte should be 8 or bigger
func BytesToFloat64(x []byte, o *Option) (float64, error) {
var fx float64
if len(x) < 8 {
return fx, errors.New("length of []byte should be 8 or bigger")
}
var ux uint64
if o == nil || o.Endian == BigEndian {
ux = binary.BigEndian.Uint64(x)
} else {
ux = binary.LittleEndian.Uint64(x)
}
return math.Float64frombits(ux), nil
}
// Float32sToBytes converts []float32 to []byte.
// Step 1. Make 2D byte slice by []float32 -> [][4]byte
// Step 2. Flatten [][4]byte to []byte
func Float32sToBytes(xs []float32, o *Option) ([]byte, error) {
bs := make([][]byte, len(xs))
for i, x := range xs {
bs[i] = Float32ToBytes(x, o)
}
return internal.FlattenBytes32(bs)
}
// BytesToFloat32s converts []byte to []float32
// Step 1. Unflatten []byte to [][4]byte
// Step 2. [][4]byte to []float32
func BytesToFloat32s(xs []byte, o *Option) ([]float32, error) {
var fs []float32
xxs, err := internal.UnflattenBytes32(xs)
if err != nil {
return nil, err
}
for _, xs := range xxs {
xs, err := BytesToFloat32(xs, o)
if err != nil {
return nil, err
}
fs = append(fs, xs)
}
return fs, nil
}
// Float64sToBytes converts []float64 to []byte.
// Step 1. Make 2D byte slice by []float64 -> [][8]byte
// Step 2. Flatten [][8]byte to []byte
func Float64sToBytes(xs []float64, o *Option) ([]byte, error) {
bs := make([][]byte, len(xs))
for i, x := range xs {
bs[i] = Float64ToBytes(x, o)
}
return internal.FlattenBytes64(bs)
}
// BytesToFloat64s converts []byte to []float64
// Step 1. Unflatten []byte to [][8]byte
// Step 2. [][8]byte to []float64
func BytesToFloat64s(xs []byte, o *Option) ([]float64, error) {
var fs []float64
xxs, err := internal.UnflattenBytes64(xs)
if err != nil {
return nil, err
}
for _, xs := range xxs {
xs, err := BytesToFloat64(xs, o)
if err != nil {
return nil, err
}
fs = append(fs, xs)
}
return fs, nil
}