{"id":20730582,"url":"https://github.com/gbmhunter/mfixedpoint","last_synced_at":"2025-04-23T22:02:33.794Z","repository":{"id":8432227,"uuid":"10021195","full_name":"gbmhunter/MFixedPoint","owner":"gbmhunter","description":"MFixedPoint is a header-only fixed-point C++ library suitable for fast arithmetic operations on systems which don't have a FPU (e.g. embedded systems).. Suitable for performing computationally intensive operations on a computing platform that does not have a floating-point unit (like most smaller embedded systems, such as Cortex-M3, CortexM0, ATmega, PSoC 5, PSoC 5 LP, PSoC 4, Arduino platforms e.t.c). Common applications include BLDC motor control and image processing. Best performance on a 32-bit or higher architecture (although 8-bit architectures should still be fine).","archived":false,"fork":false,"pushed_at":"2019-05-22T16:16:28.000Z","size":2098,"stargazers_count":164,"open_issues_count":12,"forks_count":32,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-03-30T03:51:15.245Z","etag":null,"topics":["c-plus-plus","embedded","fixed-point"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gbmhunter.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-05-12T23:35:11.000Z","updated_at":"2025-03-11T05:52:34.000Z","dependencies_parsed_at":"2022-09-18T16:13:38.561Z","dependency_job_id":null,"html_url":"https://github.com/gbmhunter/MFixedPoint","commit_stats":null,"previous_names":[],"tags_count":81,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmhunter%2FMFixedPoint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmhunter%2FMFixedPoint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmhunter%2FMFixedPoint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmhunter%2FMFixedPoint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gbmhunter","download_url":"https://codeload.github.com/gbmhunter/MFixedPoint/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250522301,"owners_count":21444511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-plus-plus","embedded","fixed-point"],"created_at":"2024-11-17T05:12:03.591Z","updated_at":"2025-04-23T22:02:33.513Z","avatar_url":"https://github.com/gbmhunter.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"===========\nMFixedPoint\n===========\n\n------------------------------------------------------------------------------------------\nA microcontroller-friendly fixed-point library specifically designed for embedded systems.\n------------------------------------------------------------------------------------------\n\n.. image:: https://travis-ci.org/gbmhunter/MFixedPoint.png?branch=master   \n\t:target: https://travis-ci.org/gbmhunter/MFixedPoint\n\n\n.. image:: https://codecov.io/gh/gbmhunter/MFixedPoint/branch/master/graph/badge.svg\n    :target: https://codecov.io/gh/gbmhunter/MFixedPoint\n\n\nDescription\n===========\n\nMFixedPoint is a header-only fixed-point C++ library suitable for fast arithmetic operations on systems which don't have a FPU (e.g. embedded systems). Suitable for performing computationally intensive operations on a computing platform that does not have a floating-point unit (like most smaller embedded systems, such as Cortex-M3, CortexM0, ATmega, PSoC 5, PSoC 5 LP, PSoC 4, Arduino platforms e.t.c). Common applications include BLDC motor control and image processing. Best performance on a 32-bit or higher architecture (although 8-bit architectures should still be fine). \n\nThe libraries are designed to be a fully-functional data types within their limits (e.g. supports operator overloads and implicit/explicit casting). Can be used with most libraries that use data type templates.\n\nFixed-point numbers are signed.\n\nNOTE: This fixed point library will usually be slower when running of a CPU which has associated floating point unit (FPU), e.g. when running on your desktop/laptop. The benchmark performance tests (found in :code:`benchmark/`) suggest simple fixed-point operations such as addition/subtraction/multiplication/division are about 10x slower than their float/double counterparts when there is a FPU. However, this library is designed to be used on CPU's where there is no FPU present, which is the case for lower-end microcontrollers such as ARM Cortex M0/M3, Atmel ATMEGA, TI MSP430's e.t.c.\n\nThe \"Slow\" Fixed-Point Library (FpS)\n------------------------------------\n\nThe \"slow\" fixed-point class is called :code:`FpS` (note that this class is not that slow, and is the recommend fixed-point class for almost all use cases). It allows for airthemtic between two fixed-point numbers that have different numbers of fractional bits. The underlying storage type of the fixed-point number and the overflow type are provided as the template parameters.\n\nIt is recommended that you use one of the predefined :code:`FpSxx` aliases (available with :code:`#include \u003cMFixedPoint/FpS.h\u003e`), which include:\n\n.. code:: cpp\n\n\tFpS8\n\tFpS16\n\tFpS32\n\tFpS64 // Note: FpS64 is not protected from intermediatary overflows!\n\nThe number of fractional bits is stored in the fixed-point object (it is a template parameter in the fast library). This gives slightly slower arithmetic speed than the fast library, but allows for more functionality and should use less code space..\n\nThe extra functionality includes the ability to add two numbers with a different number of fractional bits transparently, and to ability to cast the fixed-point number into different types (e.g. :code:`(double)myFpSNum` will convert the number to a double).\n\nWhen adding two fixed-point numbers which have a different number of fractional bits, the result's number of fractional bits is always that of lowest of the two operands. For example :code:`FpS32(3.4, 10) + FpS32(1.2, 14)` will result in same object being created as would the code :code:`FpS32(4.6, 10)`. \n\nCasting to an :code:`int` rounds to negative infinity; e.g. 5.67 becomes 5, and -12.2 becomes -13.\n\nCreate a fixed point number:\n\n.. code:: cpp\n\n\t#include \"MFixedPoint/FpS.hpp\"\n\n\t// Create a 32-bit fixed-point number.\n\t// Assign a value of 12.34\n\t// Use 8 bits for the fractional part, leaving 24 for the integer part.\n\tFpS32 fp1(12.34, 8);\n\t\n\nAddition/Subtraction/Multiplication/Division:\n\n.. code:: cpp\n\n\tFpS32 fp1(5.0, 8);\n\tFpS32 fp2(1.5, 8);\n\n\tprintf(\"add = %.2f\\n\", (fp1 + fp2).ToDouble()); // Prints \"add = 6.50\"\n\tprintf(\"sub = %.2f\\n\", (fp1 - fp2).ToDouble()); // Prints \"sub = 3.50\"\n\tprintf(\"mult = %.2f\\n\", (fp1 * fp2).ToDouble()); // Prints \"mult = 7.50\"\n\tprintf(\"div = %.2f\\n\", (fp1 / fp2).ToDouble()); // Prints \"div = 3.33\"\n\nModulus:\n\n.. code:: cpp\n\n\tFpS32 fp1(5.1, 10);\n\tFpS32 fp2(1.5, 8);\n\n\tprintf(\"mod = %.2f\\n\", (fp1 % fp2).ToDouble()); // Prints \"mod = 0.60\"\n\nConversion/Casting:\n\n.. code:: cpp\n\n\tFpS32 fp1(2.22, 8);\t\n\n\t// Using the ToXXX() functions...\n\tprintf(\"ToInt\u003cint32_t\u003e() = %i\\n\", fp1.ToInt\u003cint32_t\u003e()); // Prints \"ToInt\u003cint32_t\u003e() = 2\"\n\tprintf(\"ToDouble() = %.2f\\n\", fp1.ToDouble()); // Prints \"ToDouble() = 2.22\"\n\n\t// Direct casting is also supported\n\tprintf(\"(int32_t)fp1 = %i\\n\", (int32_t)fp1); // Prints \"(int32_t)fp1 = 2\"\n\tprintf(\"(double)fp1 = %.2f\\n\", (double)fp1); // Prints \"(double)fp1 = 2.22\"\n\nString/Stream Support:\n\n:code:`FpS` provides a :code:`ToString()` method, as well as supporting a :code:`ostream` (e.g. :code:`std::cout`).\n\n.. code:: cpp\n\n\tFpS32 fp1(4.87, 8);\n    printf(fp1.ToString());\n    std::cout \u003c\u003c fp1 \u003c\u003c std::endl; // Prints 4.87\n\nThe \"Fast\" Fixed-Point Library (FpF)\n------------------------------------\n\nThe number of fractional bits is given as a template parameter (e.g. :code:`FpF32\u003c12\u003e(3.4)` will create the number 3.4 with 12 bits of fractional precision). It is not stored in the fixed-point object. This gives the fastest possible arithmetic speeds, at the expense of loosing some functionality and a tad more code space.\n\nArithmetic operations between two FpF objects that have a different template parameter (fractional precision) is not directly supported. Instead, you will have to convert one of the FpF objects to the same fraction precision first, and then do the arithmetic operation.\n\nOverflows\n---------\n\n:code:`FpS8, FpS16, FpS32` are protected from intermediary overflows. :code:`FpS64` is not, due to the lack of a :code:`int128_t` type on most embeded platforms.\n\nOn any 32-bit architecture, :code:`FpS64` numbers will be slower than :code:`FpS64` numbers. Use only if 32-bit numbers don't offer the range/precision required.\n\n\nBenchmarking\n============\n\nThis library contains a benchmarking program in :code:`benchmark/` which runs operations on the fixed-point libraries and reports back on their performance. It is run automatically as part of :code:`make all`.\n\nThe benchmarking is compared to software-based float arithmetic (using the custom header SoftFloat.hpp), since most benchmarking will be run on a development computer which has an FPU which will be used if float + float was written in code. If benchmarking on a device which does not have an FPU, you should compare the fixed-point operations against the native software float arithmetic implementation instead. Software-based 32-bit float addition and multiplication are performed and compared with the equivalent fixed-point operations.\n\nThese benchmark results were computed on a x64 Ubuntu machine running inside a virtual machine. 100k samples were taken for each type of test, and the average time provided.\n\n+----------------+--------+--------+--------+--------+----------------+----------------+\n| Arithmetic     | FpF32  | FpF64  | FpS32  | FpS64  | Software Float | Hardware Float |\n+================+========+========+========+========+================+================+\n| Addition       | 6.7ns  | 8.2ns  | 10.6ns | 14.2ns | 30.1ns         | 3.4ns          |\n+----------------+--------+--------+--------+--------+----------------+----------------+\n| Subtraction    | 7.5ns  | 7.5ns  | 14.0ns | 10.4ns | n/a            | 2.6ns          |\n+----------------+--------+--------+--------+--------+----------------+----------------+\n| Multiplication | 10.3ns | 10.1ns | 12.2ns | 10.4ns | 32.0ns         | 2.5ns          |\n+----------------+--------+--------+--------+--------+----------------+----------------+\n| Division       | 19.0ns | 18.0ns | 10.8ns | 19.8ns | n/a            | 5.1ns          |\n+----------------+--------+--------+--------+--------+----------------+----------------+\n\nPlatform Independent\n====================\n\nThe library is designed to be platform independent. Port-specific functions are declared in separate files, Port.cpp and Port.hpp. These files include functions for printing debug information. Fill in the functions as desired.\n\nThis library has been tested on:\n\n- ARM Cortex-M3 microcontrollers\n- Linux (Ubuntu)\n- A CodeAnywhere \"DevBox\"\n\nCompiling\n=========\n\nEither use cmake with the provided :code:`CMakeLists.txt` in the root directory, or integrate the source files into an IDE (for an embedded platform).\n\nThe cmake method will build the fixed point library and automatically runs all unit tests and the benchmark program.\n\n\n.. code:: bash\n\n\t~$ git clone https://github.com/gbmhunter/MFixedPoint.git\n\t~$ cd MFixedPoint\n\t~/MFixedPoint$ mkdir build\n\t~/MFixedPoint$ cd build\n\t~/MFixedPoint/build$ cmake ..\n\t~/MFixedPoint/build$ make\n\t\nYou can run the tests manually by calling:\n\n.. code:: bash\n\n\t~/MFixedPoint/build$ ./test/MFixedPointTests\n\nExamples\n========\n\nSee the unit tests in :code:`test/` for more usage examples!\n\n.. code:: cpp\n\n\t// System includes\n\t#include \u003ciostream\u003e\n\n\t// 3rd party includes\n\t#include \"MFixedPoint/FpS.hpp\"\n\t#include \"MFixedPoint/FpF.hpp\"\n\n\tusing namespace mn::MFixedPoint;\n\n\tint main() {\n\n\t\t//================================================================================================//\n\t\t//================================= Slow Fixed-Point Numbers (FpS) ===============================//\n\t\t//================================================================================================//\n\n\t\t// Creating a 32-bit \"slow\" fixed-point number (notice the slightly different syntax to FpF)\n\t\tFpS32 fpSNum1(12.23, 12);\n\t\tstd::cout \u003c\u003c \"fpSNum1 = \" \u003c\u003c (double)fpSNum1 \u003c\u003c std::endl;\n\n\t\tFpS32 fpSNum2(5.12, 16);\n\t\tstd::cout \u003c\u003c \"fpSNum2 = \" \u003c\u003c (double)fpSNum2 \u003c\u003c std::endl;\n\t\t\n\t\tstd::cout \u003c\u003c \"fpSNum1 + fpSNum2 = \" \u003c\u003c (double)(fpSNum1 + fpSNum2) \u003c\u003c std::endl;\n\t\tstd::cout \u003c\u003c \"fpSNum1 - fpSNum2 = \" \u003c\u003c (double)(fpSNum1 - fpSNum2) \u003c\u003c std::endl;\n\t\tstd::cout \u003c\u003c \"fpSNum1 * fpSNum2 = \" \u003c\u003c (double)(fpSNum1 * fpSNum2) \u003c\u003c std::endl;\n\t\tstd::cout \u003c\u003c \"fpSNum1 / fpSNum2 = \" \u003c\u003c (double)(fpSNum1 / fpSNum2) \u003c\u003c std::endl;\n\t\tstd::cout \u003c\u003c \"fpSNum1 % fpSNum2 = \" \u003c\u003c (double)(fpSNum1 % fpSNum2) \u003c\u003c std::endl;\n\n\t\t//================================================================================================//\n\t\t//================================= Fast Fixed-Point Numbers (FpF) ===============================//\n\t\t//================================================================================================//\n\n\t\t// Create two 32-bit fast fixed-point numbers with 24 decimal bits and 8 fractional bits.\n\t\t// This constructor converts from doubles\n\t\tFpF32\u003c8\u003e fpNum1(3.2);\n\t\tFpF32\u003c8\u003e fpNum2(0.6);\n\t\t\n\t\t// Performing a quick fixed-point addition\n\t\tauto fpNum3 = fpNum1 + fpNum2;\n\t\t\n\t\t// Performing a quick fixed-point multiplication\n\t\tauto fpNum4 = fpNum1 * fpNum2;\n\t\t\n\t\t// Printing the result as a double, using the Fix32ToDouble() method\n\t\t// Note that if you use slow fixed-point data type instead, you can \n\t\t// directly cast one to a double \n\t\tstd::cout \u003c\u003c \"My fast 32-bit fixed-point number = \" \u003c\u003c (double)fpNum4;\n\t\t\n\t\t// Converting between different precisions. Requires access to raw value just like\n\t\t// when doing fixed-point to double conversion.\n\t\tFpF32\u003c20\u003e aHigherPrecisionNum(7.5);\n\t\t// FpF32\u003c12\u003e aLowerPrecisionNum.rawVal = aHigherPrecisionNum.rawVal \u003e\u003e (20 - 12);\n\t\t\n\t\t// You can use 64-bit fixed point numbers in exactly the same way!\n\t\tFpF64\u003c48\u003e aFp64Num(4.58676);\n\t\t\n\t\treturn 0;\n\t}\n\nVisual Studio Code\n==================\n\nProject files for Visual Studio Code are included in this repository. Include paths have been added to :code:`c_cpp_properties.json` to improve auto-complete. This includes the directory :code:`${workspaceRoot}/build/external/include` (which contains the 3rd party libraries MFixedPoint depends on that are automatically downloaded by CMake) but is only valid once CMake has been run at least once from with a build directory called :code:`build`.\n\nCode Dependencies\n=================\n\nThe following table lists all of MFixedPoint's dependencies.\n\n====================== ==================== ======================================================================\nDependency             Delivery             Usage\n====================== ==================== ======================================================================\n\u003ccstdint.h\u003e            C std lib.           For platform agnostic fixed-width integers.\n\u003costream\u003e              C++ std lib.\n\u003cstring\u003e               C++ std lib.\n\u003ctype_traits\u003e          C++ std lib.\nMUnitTest              External module      Framework for unit tests.\n====================== ==================== ======================================================================","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbmhunter%2Fmfixedpoint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgbmhunter%2Fmfixedpoint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbmhunter%2Fmfixedpoint/lists"}