-
Notifications
You must be signed in to change notification settings - Fork 2
/
genq.go
118 lines (101 loc) · 1.86 KB
/
genq.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
// Copyright 2018 Iri France SAS. All rights reserved. Use of this source code
// is governed by a license that can be found in the License file.
package main
import (
"flag"
"log"
"math"
"os"
"text/template"
)
var q = flag.Uint("q", 52, "number of fraction bits")
var qTempl = `// +build q{{.Q}}
//
// Automatically generated by github.com/irifrance/fx/cmd/genq
// Do not edit
package fx
const (
Pi = {{.Pi}}
E = {{.E}}
Sqrt2 = {{.Sqrt2}}
)
const (
FrBits = {{.Q}}
)
var cordicAtans = []T{
{{range .CordicAtans -}}
{{.}},
{{end -}}
}
var cordicKs = []T{
{{range .CordicKs -}}
{{.}},
{{end -}}
}
`
type T int64
var frBits uint
var One = T(1 << frBits)
var Iota = T(1)
var Sign = T(-1)
func Float64(f float64) T {
s := T(Iota)
if f < 0.0 {
f = -f
s = Sign
}
fone := float64(One)
g := math.Floor(fone*f + 0.5)
return s * T(int64(g))
}
type tInfo struct {
Pi, E, Ln2, Sqrt2 T
Q uint
CordicAtans []T
CordicKs []T
}
func cordicAtans() []T {
atan2ps := make([]T, *q)
for i := uint(0); i < frBits; i++ {
f := math.Atan(1.0 / float64(int64(1)<<i))
atan2ps[i] = Float64(f)
}
return atan2ps
}
func cordicKs() []T {
cKs := make([]T, *q)
p := 1.0
var q float64
for i := uint(0); i < frBits; i++ {
q = 1.0 / float64(int64(1)<<(2*i))
p *= 1.0 / math.Sqrt(1.0+q)
cKs[i] = Float64(p)
}
// overflow...
last := Iota
for i, v := range cKs {
if v == 0 {
cKs[i] = last
}
last = cKs[i]
}
return cKs
}
func main() {
flag.Parse()
One = T(1 << *q)
frBits = *q
ti := &tInfo{
Q: uint(*q),
Pi: Float64(math.Pi),
E: Float64(math.E),
Ln2: Float64(math.Ln2),
Sqrt2: Float64(math.Sqrt2),
CordicAtans: cordicAtans(),
CordicKs: cordicKs()}
qt := template.New("q")
qt, _ = qt.Parse(qTempl)
if err := qt.Execute(os.Stdout, ti); err != nil {
log.Fatal(err)
}
}