Merge branch 'master' of gitlab:wintermute/hackover2013-badge-firmware
[hackover2013-badge-firmware.git] / badge / util / fixed_point.h
1 #ifndef INCLUDED_FIXED_POINT_H
2 #define INCLUDED_FIXED_POINT_H
3
4 #include <stdint.h>
5 #include <stdbool.h>
6
7 /* Unterstes Byte als Nachkomma. 16 Bit Nutzlast! Sonst geht Multiplikation flöten. */
8 typedef struct { int32_t data; } fixed_point;
9
10 static inline fixed_point fixed_point_add(fixed_point x, fixed_point y) { fixed_point r = { x.data + y.data }; return r; }
11 static inline fixed_point fixed_point_sub(fixed_point x, fixed_point y) { fixed_point r = { x.data - y.data }; return r; }
12 static inline fixed_point fixed_point_mul(fixed_point x, fixed_point y) { fixed_point r = { x.data * y.data / 256 }; return r; }
13 static inline fixed_point fixed_point_div(fixed_point x, fixed_point y) { fixed_point r = { (x.data * 256) / y.data }; return r; }
14
15 static inline fixed_point fixed_point_neg(fixed_point x) { fixed_point r = { -x.data }; return r; }
16 static inline fixed_point fixed_point_abs(fixed_point x) { fixed_point r = { x.data < 0 ? -x.data : x.data }; return r; }
17
18 static inline bool fixed_point_lt(fixed_point x, fixed_point y) { return x.data < y.data; }
19 static inline bool fixed_point_gt(fixed_point x, fixed_point y) { return x.data > y.data; }
20 static inline bool fixed_point_le(fixed_point x, fixed_point y) { return x.data <= y.data; }
21 static inline bool fixed_point_ge(fixed_point x, fixed_point y) { return x.data >= y.data; }
22 static inline bool fixed_point_eq(fixed_point x, fixed_point y) { return x.data == y.data; }
23 static inline bool fixed_point_ne(fixed_point x, fixed_point y) { return x.data != y.data; }
24
25 #define FIXED_POINT_I(x, y) { ((x) * 256) + ((y) * 256 / 1000) }
26 #define FIXED_INT_I(x) FIXED_POINT_I(x, 0)
27
28 static inline fixed_point FIXED_POINT(int32_t x, int32_t y) {
29 fixed_point r = FIXED_POINT_I(x, y);
30 return r;
31 }
32
33 static inline fixed_point FIXED_INT(int32_t x) { return FIXED_POINT(x, 0); }
34
35 // sign bit is shifted in if x.data < 0, so this is x.data / 256 - (x.data < 0).
36 // This means 0.123 is cast to 1, which is what we want when we cast a model coordinate
37 // to a screen coordinate.
38 static inline int fixed_point_cast_int(fixed_point x) { return x.data >> 8; }
39
40 static inline fixed_point fixed_point_min(fixed_point x, fixed_point y) { return fixed_point_lt(x, y) ? x : y; }
41 static inline fixed_point fixed_point_max(fixed_point x, fixed_point y) { return fixed_point_gt(x, y) ? x : y; }
42
43 #endif
This page took 0.04643 seconds and 5 git commands to generate.