Skip to content

Commit 47b35b2

Browse files
Add fixed point math library (#316)
* Add fixed point math library * Use union and bitfield for storage type Address many of the review comments as well * Expand fixed point library to add better handling for int types and promotion and also add multiplication * Add newline * Finish change; rework slightly - Like C integers, silently truncate on implicit conversion to a smaller type. - Compound assignments convert to the join type above then truncate, as C integers do. * Fix example * Minor refactor * Some fixes --------- Co-authored-by: Daniel Thornburgh <[email protected]>
1 parent 450982a commit 47b35b2

File tree

3 files changed

+640
-0
lines changed

3 files changed

+640
-0
lines changed

examples/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ endfunction()
1313
add_executable(minimal minimal.c)
1414
install_example(minimal)
1515
if(HOSTED)
16+
add_executable(fixed-point fixed-point.cc)
17+
install_example(fixed-point)
1618
add_executable(hello-getchar hello-getchar.c)
1719
install_example(hello-getchar)
1820
add_executable(hello-malloc hello-malloc.c)

examples/fixed-point.cc

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#undef NDEBUG
2+
#include <assert.h>
3+
#include <fixed_point.h>
4+
5+
// This file is an example of how to use the high level fixed point
6+
// library in fixed_point.h. The fixedpoint::Value class provides a
7+
// typesafe wrapper for fixed point mathematical operations and
8+
// convenience methods for accessing the integral and decimal parts.
9+
10+
int main() {
11+
// Creates a signed fixed point number with 100 as the integral part
12+
// The full representation of the number is 0x6400 where 0x64 is the
13+
// integer part and 0x00 is the fractional part.
14+
FixedPoint<8, 8> basic_number{100};
15+
16+
// Math operators work out of the box
17+
// This will add 19 to the integral part
18+
basic_number += 19;
19+
20+
// Integer and fractional parts can be accessed individually
21+
assert( basic_number.as_i() == 119 );
22+
23+
// Now for the fun part, here's a second number but with a fractional part
24+
// This number in hexadecimal is 0x0110
25+
FixedPoint<8, 8> second_number{1, 16};
26+
27+
// Subtraction works as well.
28+
basic_number -= second_number;
29+
// The new basic_number integral part is now 117 (since we subtracted a fraction part)
30+
assert( basic_number.as_i() == 117 );
31+
// The fractional part is
32+
assert( basic_number.as_f() == 0xf0 );
33+
34+
// Now that the basics are out of the way, let's start using the helper methods
35+
// in the literals namespace
36+
using namespace fixedpoint_literals;
37+
38+
// For the common 8.8 and 12.4 fixed point numbers, user defined literals are
39+
// provided for converting from floating point numbers at compile time.
40+
// This converts 9.87 into an 12.4 number (0x009e)
41+
auto third_number = 9.87_12_4;
42+
43+
// Comparisons work between fixed point numbers or integer numbers
44+
// Additionally fixed point numbers will be converted to other fixed point
45+
// numbers automatically when performing math operations.
46+
assert(third_number + second_number <= basic_number);
47+
assert(basic_number < 119);
48+
49+
// fixed point numbers can be signed or unsigned as well with the optional
50+
// third parameter. They are signed by default like other integer types
51+
// There is also a matching literal type for unsigned numbers `_u8_8`
52+
// as well as an explicit signed version `_s8_8`
53+
fu8_8 unsigned_number = 40.4_u8_8;
54+
// The type is not required of course, the following also works.
55+
auto unsigned_number2 = 40.4_u8_8;
56+
57+
unsigned_number += 200;
58+
// Since its unsigned, it will be treated as a positive value instead
59+
assert ( unsigned_number > 200 );
60+
61+
return 0;
62+
}

0 commit comments

Comments
 (0)