14
|
1 # Q: Fixed Point Number Library
|
|
2
|
|
3 | Project | Q: Fixed Point Number Library |
|
|
4 | --------- | --------------------------------- |
|
|
5 | Author | Richard James Howe |
|
|
6 | Copyright | 2018 Richard James Howe |
|
|
7 | License | MIT |
|
|
8 | Email | howe.r.j.89@gmail.com |
|
|
9 | Website | <https://github.com/howerj/q> |
|
|
10
|
|
11 This is a small fixed point number library designed for embedded use. It
|
|
12 implements all of your favorite transcendental functions, plus only the best
|
|
13 basic operators, selected for your calculating pleasure. The format is a signed
|
|
14 [Q16.16][], which is good enough for [Doom][] and good enough for you.
|
|
15
|
|
16 The default [makefile][] target builds the library and a test program, which will
|
|
17 require a [C][] compiler (and Make). The library is small enough that is can be
|
|
18 easily modified to suite your purpose. The dependencies are minimal; they are few
|
|
19 string handling functions, and '[tolower][]' for numeric input. This should allow
|
|
20 the code to ported to the platform of your choice. The 'run' make target builds
|
|
21 the test program (called 'q') and runs it on some input. The '-h' option will
|
|
22 spit out a more detailed help.
|
|
23
|
|
24 I would compile the library with the '-fwrapv' option enabled, you might
|
|
25 be some kind of Maverick who doesn't play by no rules however.
|
|
26
|
|
27 The trigonometric functions, and some others, are implemented internally with
|
|
28 [CORDIC][].
|
|
29
|
|
30 Of note, all operators are bounded by minimum and maximum values which are not
|
|
31 shown in the following table and by default all arithmetic is saturating. The
|
|
32 effective input range of a number might lower than what is possible given a
|
|
33 mathematical functions definition - either because of the limited range of the
|
|
34 [Q16.16][] type, or because the implementation of a function introduces too
|
|
35 much error along some part of its' input range. Caveat Emptor (although you're
|
|
36 not exactly paying for this library now, are you? Caveat lector perhaps).
|
|
37
|
|
38 ( This table needs completing, specifically the input ranges... )
|
|
39
|
|
40 | C Function | Operator | Input Range | Asserts | Notes |
|
|
41 | ------------- | ----------- | ----------- | -------- | ----------------------------------------------- |
|
|
42 | qadd(a, b) | a + b | | | Addition |
|
|
43 | qsub(a, b) | a \- b | | | Subtraction |
|
|
44 | qdiv(a, b) | a / b | b != 0 | Yes | Division |
|
|
45 | qmul(a, b) | a \* b | | | Multiplication |
|
|
46 | qrem(a, b) | a rem b | b != 0 | Yes | Remainder: remainder after division |
|
|
47 | qmod(a, b) | a mod b | b != 0 | Yes | Modulo |
|
|
48 | qsin(theta) | sin(theta) | | | Sine |
|
|
49 | qcos(theta) | cos(theta) | | | Cosine |
|
|
50 | qtan(theta) | tan(theta) | | | Tangent |
|
|
51 | qcot(theta) | cot(theta) | | | Cotangent |
|
|
52 | qhypot(a, b) | hypot(a, b) | | | Hypotenuse; sqrt(a\*a + b\*b) |
|
|
53 | qasin(x) | asin(x) | abs(x) <= 1 | Yes | Arcsine |
|
|
54 | qacos(x) | acos(x) | abs(x) <= 1 | Yes | Arccosine |
|
|
55 | qatan(t) | atan(t) | | | Arctangent |
|
|
56 | qsinh(a) | sinh(a) | | | Hyperbolic Sine |
|
|
57 | qcosh(a) | cosh(a) | | | Hyperbolic Cosine |
|
|
58 | qtanh(a) | tanh(a) | | | Hyperbolic Tangent |
|
|
59 | qasinh(a) | asinh(a) | | | Inverse Hyperbolic Sine |
|
|
60 | qacosh(a) | acosh(a) | | | Inverse Hyperbolic Cosine |
|
|
61 | qatanh(a) | atanh(a) | | | Inverse Hyperbolic Tangent |
|
|
62 | qexp(e) | exp(e) | e < ln(MAX) | No | Exponential function, High error for 'e' > ~7. |
|
|
63 | qlog(n) | log(n) | n > 0 | Yes | Natural Logarithm |
|
|
64 | qsqrt(x) | sqrt(x) | n >= 0 | Yes | Square Root |
|
|
65 | qround(q) | round(q) | | | Round to nearest value |
|
|
66 | qceil(q) | ceil(q) | | | Round up value |
|
|
67 | qtrunc(q) | trunc(q) | | | Truncate value |
|
|
68 | qfloor(q) | floor(q) | | | Round down value |
|
|
69 | qnegate(a) | -a | | | Negate a number |
|
|
70 | qabs(a) | abs(a) | | | Absolute value of a number |
|
|
71 | qfma(a, b, c) | (a\*b)+c | | | Fused Multiply Add, uses Q32.32 internally |
|
|
72 | qequal(a, b) | a == b | | | |
|
|
73 | qsignum(a) | signum(a) | | | Signum function |
|
|
74 | qsign(a) | sgn(a) | | | Sign function |
|
|
75 | | | | | |
|
|
76
|
|
77 For the round/ceil/trunc/floor functions the following table from the
|
|
78 [cplusplus.com][] helps:
|
|
79
|
|
80 | value | round | floor | ceil | trunc |
|
|
81 | ----- | ----- | ----- | ---- | ----- |
|
|
82 | 2.3 | 2.0 | 2.0 | 3.0 | 2.0 |
|
|
83 | 3.8 | 4.0 | 3.0 | 4.0 | 3.0 |
|
|
84 | 5.5 | 6.0 | 5.0 | 6.0 | 5.0 |
|
|
85 | -2.3 | -2.0 | -3.0 | -2.0 | -2.0 |
|
|
86 | -3.8 | -4.0 | -4.0 | -3.0 | -3.0 |
|
|
87 | -5.5 | -6.0 | -6.0 | -5.0 | -5.0 |
|
|
88
|
|
89 Have fun with the adding, and subtracting, and stuff, I hope it goes well. It
|
|
90 would be cool to make an [APL][] interpreter built around this library. Testing
|
|
91 would become much easier as you could use programming language constructs to
|
|
92 create new tests over larger ranges of numbers.
|
|
93
|
|
94 [APL]: https://en.wikipedia.org/wiki/APL_(programming_language)
|
|
95 [Doom]: https://en.wikipedia.org/wiki/Doom_(1993_video_game)
|
|
96 [tolower]: http://www.cplusplus.com/reference/cctype/tolower/
|
|
97 [makefile]: https://en.wikipedia.org/wiki/Make_(software)
|
|
98 [C]: https://en.wikipedia.org/wiki/C_%28programming_language%29
|
|
99 [cplusplus.com]: http://www.cplusplus.com/reference/cmath/round/
|
|
100 [Q16.16]: https://en.wikipedia.org/wiki/Fixed-point_arithmetic
|
|
101 [CORDIC]: https://en.wikipedia.org/wiki/CORDIC
|
|
102 [VHDL]: https://en.wikipedia.org/wiki/VHDL
|
|
103 [FPGA]: https://en.wikipedia.org/wiki/Field-programmable_gate_array
|
|
104
|
|
105 <style type="text/css">body{margin:40px auto;max-width:850px;line-height:1.6;font-size:16px;color:#444;padding:0 10px}h1,h2,h3{line-height:1.2}</style>
|