annotate q/readme.md @ 30:92fdf2ef995d default tip

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