Last active
June 24, 2017 09:30
-
-
Save johnmcfarlane/b0481555a68cb8fc410cfc4007df16d1 to your computer and use it in GitHub Desktop.
example of zero-cost abstraction using the fixed_point library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Signed 15:16 Fixed-Point Square Function Using sg14::elastic | |
#include <https://gist.githubusercontent.com/johnmcfarlane/23b8bc5fefb77d482306c5bc837b5df1/raw/ed6cdfc3de42ae3c140bbbdd0ce5b8bc131d1f02/fixed_point.h> | |
using namespace sg14; | |
// square a nunber using 15:16 fixed-point arithmetic | |
// without using a fixed-point library | |
float square_int(float input) { | |
// user must scale values by the correct amount | |
auto fixed = static_cast<int32_t>(input * 65536.f); | |
// user must remember to widen the result to avoid overflow | |
auto prod = int64_t{fixed} * fixed; | |
// user must remember that the scale also was squared | |
return prod / 4294967296.f; | |
} | |
// the same function using sg14::elastic_integer | |
float square_elastic_integer(float input) { | |
auto fixed = elastic_integer<31>{input * 65536.f}; | |
// elastic_integer automatically widens the result | |
auto prod = fixed * fixed; | |
// but the user must still do all the scaling themselves | |
return static_cast<float>(prod) / 4294967296.f; | |
} | |
// the same function using sg14::fixed_point | |
float square_fixed_point(float input) { | |
// fixed_point handles scaling | |
auto fixed = fixed_point<int32_t, -16>{input}; | |
// but it uses int under the hood; user must still widen | |
auto prod = fixed_point<int64_t, -16>{fixed} * fixed; | |
return static_cast<float>(prod); | |
} | |
// finally, the composition of fixed_point and elastic_integer | |
float square_elastic(float input) { | |
// alias to fixed_point<elastic_integer<31, int>, -16> | |
auto fixed = elastic_fixed_point<15, 16>{input}; | |
// concise, safe and zero-cost! | |
auto prod = fixed * fixed; | |
return static_cast<float>(prod); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment