-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfixmath.nim
131 lines (103 loc) · 5.1 KB
/
fixmath.nim
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
{.compile: "libfixmath/libfixmath/fix16.c".}
{.compile: "libfixmath/libfixmath/fix16_exp.c".}
{.compile: "libfixmath/libfixmath/fix16_sqrt.c".}
{.compile: "libfixmath/libfixmath/fix16_str.c".}
{.compile: "libfixmath/libfixmath/fix16_trig.c".}
{.compile: "libfixmath/libfixmath/fract32.c".}
{.compile: "libfixmath/libfixmath/uint32.c".}
import os
const ThisPath* = currentSourcePath.splitPath.head
{.passC: "-I"&ThisPath&"/libfixmath/libfixmath/".}
type
fix16* = distinct int32
# Basic arithmetic
proc f16Add(a, b: fix16): fix16 {.importc: "fix16_add", header: "fixmath.h", cdecl.}
proc f16Sub(a, b: fix16): fix16 {.importc: "fix16_sub", header: "fixmath.h", cdecl.}
proc f16Mul(a, b: fix16): fix16 {.importc: "fix16_mul", header: "fixmath.h", cdecl.}
proc f16Div(a, b: fix16): fix16 {.importc: "fix16_div", header: "fixmath.h", cdecl.}
proc f16Mod(a, b: fix16): fix16 {.importc: "fix16_mod", header: "fixmath.h", cdecl.}
# Saturated arithmetic
proc satAdd(a, b: fix16): fix16 {.importc: "fix16_sadd", header: "fixmath.h", cdecl.}
proc satSub(a, b: fix16): fix16 {.importc: "fix16_ssub", header: "fixmath.h", cdecl.}
proc satMul(a, b: fix16): fix16 {.importc: "fix16_smul", header: "fixmath.h", cdecl.}
proc satDiv(a, b: fix16): fix16 {.importc: "fix16_sdiv", header: "fixmath.h", cdecl.}
# Math functions
proc abs*(x: fix16): fix16 {.importc: "fix16_abs", header: "fixmath.h", cdecl.}
proc floor*(x: fix16): fix16 {.importc: "fix16_floor", header: "fixmath.h", cdecl.}
proc ceil*(x: fix16): fix16 {.importc: "fix16_ceil", header: "fixmath.h", cdecl.}
proc min*(x, y: fix16): fix16 {.importc: "fix16_min", header: "fixmath.h", cdecl.}
proc max*(x, y: fix16): fix16 {.importc: "fix16_max", header: "fixmath.h", cdecl.}
proc clamp*(x, lo, hi: fix16): fix16 {.importc: "fix16_clamp", header: "fixmath.h", cdecl.}
# Trig Functions
proc sinParabola*(inAngle: fix16): fix16 {.importc: "fix16_sin_parabola", header: "fixmath.h", cdecl.}
proc sin*(inAngle: fix16): fix16 {.importc: "fix16_sin", header: "fixmath.h", cdecl.}
proc cos*(inAngle: fix16): fix16 {.importc: "fix16_cos", header: "fixmath.h", cdecl.}
proc tan*(inAngle: fix16): fix16 {.importc: "fix16_tan", header: "fixmath.h", cdecl.}
proc asin*(inValue: fix16): fix16 {.importc: "fix16_asin", header: "fixmath.h", cdecl.}
proc acos*(inValue: fix16): fix16 {.importc: "fix16_acos", header: "fixmath.h", cdecl.}
proc atan*(inValue: fix16): fix16 {.importc: "fix16_atan", header: "fixmath.h", cdecl.}
proc atan2*(inY, inX: fix16): fix16 {.importc: "fix16_atan2", header: "fixmath.h", cdecl.}
proc radToDeg*(radians: fix16): fix16 {.importc: "fix16_rad_to_deg", header: "fixmath.h", cdecl.}
proc degToRad*(degrees: fix16): fix16 {.importc: "fix16_deg_to_rad", header: "fixmath.h", cdecl.}
# Additional functions
proc sqrt*(inValue: fix16): fix16 {.importc: "fix16_sqrt", header: "fixmath.h", cdecl.}
proc square*(x: fix16): fix16 {.importc: "fix16_sq", header: "fixmath.h", cdecl.}
proc exp*(inValue: fix16): fix16 {.importc: "fix16_exp", header: "fixmath.h", cdecl.}
proc log*(inValue: fix16): fix16 {.importc: "fix16_log", header: "fixmath.h", cdecl.}
proc log2*(x: fix16): fix16 {.importc: "fix16_log2", header: "fixmath.h", cdecl.}
proc slog2*(x: fix16): fix16 {.importc: "fix16_slog2", header: "fixmath.h", cdecl.}
# Utility functions
proc toString*(value: fix16, buf: cstring, decimals: int): void {.importc: "fix16_to_str", header: "fixmath.h", cdecl.}
converter toFix16*(a: int): fix16 {.importc: "fix16_from_int", header: "fixmath.h", cdecl.}
converter toFix16*(a: float): fix16 {.importc: "fix16_from_float", header: "fixmath.h", cdecl.}
converter toInt*(a: fix16): int {.importc: "fix16_to_int", header: "fixmath.h", cdecl.}
converter toFloat*(a: fix16): float {.importc: "fix16_to_float", header: "fixmath.h", cdecl.}
proc `+`*(a, b: fix16): fix16 =
result = f16Add(a, b)
proc `-`*(a, b: fix16): fix16 =
result = f16Sub(a, b)
proc `*`*(a, b: fix16): fix16 =
result = f16Mul(a, b)
proc `/`*(a, b: fix16): fix16 =
result = f16Div(a, b)
proc `%`*(a, b: fix16): fix16 =
result = f16Mod(a, b)
proc `|+|`*(a, b: fix16): fix16 =
result = satAdd(a, b)
proc `|-|`*(a, b: fix16): fix16 =
result = satSub(a, b)
proc `|*|`*(a, b: fix16): fix16 =
result = satMul(a, b)
proc `|/|`*(a, b: fix16): fix16 =
result = satDiv(a, b)
proc `!=`*(a, b: fix16): bool =
cast[int32](a) != cast[int32](b)
proc `==`*(a, b: fix16): bool =
cast[int32](a) == cast[int32](b)
proc `>`*(a, b: fix16): bool =
cast[int32](a) > cast[int32](b)
proc `<`*(a, b: fix16): bool =
cast[int32](a) < cast[int32](b)
proc `>=`*(a, b: fix16): bool =
cast[int32](a) >= cast[int32](b)
proc `<=`*(a, b: fix16): bool =
cast[int32](a) <= cast[int32](b)
proc `$`*(a: fix16): string =
# The longest string that toString returns is 13 bytes long
result = newString(13)
toString(a, result.cstring, 7)
when isMainModule:
let a: fix16 = 1
let b: fix16 = 2.2
let c = (0xffff).toFix16
echo "A: ", a
echo "B: ", b
echo "added: ", a + b
echo "subtracted: ", a - b
echo "multiplied: ", a * b
echo "divided: ", a / b
echo "Saturated Add: ", c |+| c
echo "A > B: ", a > b
echo "A < B: ", a < b
echo "A < 2: ", a < 2
echo "2 < A: ", 2 < a