Last active
December 27, 2015 02:11
-
-
Save cho45/2761fb938ccbcf0590ca to your computer and use it in GitHub Desktop.
This file contains hidden or 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
//#!g++ -O3 -std=c++14 cpp.cpp -o a.out && ./a.out ; ;: | |
#include <cstdio> | |
#include <stdint.h> | |
#include <type_traits> | |
template <uint8_t int_bits, uint8_t fractional_bits, class T> | |
inline float fixed_point_to_float(const T fixed) { | |
static_assert(std::is_unsigned<T>::value, "argument must be unsigned"); | |
constexpr uint8_t msb = int_bits + fractional_bits - 1; | |
constexpr T mask = (T)~(((T)~(0)) << msb); | |
constexpr float deno = 1<<fractional_bits; | |
if (fixed & (1<<msb)) { | |
// negative | |
return -( (float)( (~fixed & mask) + 1) / deno); | |
} else { | |
// positive | |
return (float)fixed / deno; | |
} | |
} | |
bool is(float got, float expected, const char* desc = NULL) { | |
const bool ret = got == expected; | |
if (ret) { | |
printf("ok\n"); | |
} else { | |
printf("not ok %f != %f # %s\n", got, expected, desc ? desc : ""); | |
} | |
return ret; | |
} | |
int main (int argc, char* argv[]) { | |
// from ADT7410 datasheet | |
is(fixed_point_to_float<9, 4>((uint16_t)0b0000000000001), 0.0625); | |
is(fixed_point_to_float<9, 4>((uint16_t)0b0100101100000), 150.0); | |
is(fixed_point_to_float<9, 4>((uint16_t)0b0000000000000), 0); | |
is(fixed_point_to_float<9, 4>((uint16_t)0b1110010010000), -55.0); | |
is(fixed_point_to_float<9, 4>((uint16_t)0b1111111111111), -0.0625); | |
is(fixed_point_to_float<9, 4>((uint32_t)0b1111111111111), -0.0625 ); | |
/** compile error : argument must be unsigned | |
printf("%f\n", fixed_point_to_float<9, 4>((int16_t)0b1111111111111)); | |
*/ | |
// from MCP3425 | |
is(fixed_point_to_float<1, 11>((uint16_t)0x001) * (2.048), 1e-3); | |
is(fixed_point_to_float<1, 13>((uint16_t)0x001) * (2.048), 250e-6); | |
is(fixed_point_to_float<1, 15>((uint16_t)0x001) * (2.048), 62.5e-6); | |
// test dynamic variable | |
volatile uint16_t x = 0x001; | |
is(fixed_point_to_float<1, 11>(x) * (2.048), 1e-3); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment