C++ fixed_point_01
Date: 2024-06-09Last modified: 2024-06-09
Table of contents
// Use differents amounts of bits for fractional part
for( uint32_t SHIFT_AMOUNT : { 28, 24, 16, 8 } ) {
// Utility for printing
auto print_binary = [SHIFT_AMOUNT]( uint32_t value, auto comment ) {
std::bitset<32> bits{ value };
std::string value_string = bits.to_string();
value_string.insert( 32 - SHIFT_AMOUNT, "📍" );
std::cout << value_string << "\t" << value << "\t" << comment << std::endl;
};
uint32_t SHIFT_MASK = ( 1 << SHIFT_AMOUNT ) - 1;
std::cout << "====================================================" << std::endl;
std::cout << "SHIFT_AMOUNT = " << SHIFT_AMOUNT << std::endl;
std::cout << "SHIFT_MASK = " << SHIFT_MASK << std::endl;
print_binary( SHIFT_MASK, "SHIFT_MASK" );
uint32_t price = 500 << SHIFT_AMOUNT;
if( ( price >> SHIFT_AMOUNT ) != 500 ) {
std::cout << "⛔ no enought bits for integer part holds our example" << std::endl;
}
print_binary( price, "price = 500" );
price += 10 << SHIFT_AMOUNT;
print_binary( price, "price += 10" );
price *= 3;
print_binary( price, "price *= 3" );
price /= 4; // now our price is ((500 + 10) * 3) / 4 = 382.5
print_binary( price, "price /= 4" );
// C style print
printf( "price integer is %d\n", price >> SHIFT_AMOUNT );
printf( "price fraction is %d\n", price & SHIFT_MASK );
printf( "price fraction in decimal is %f\n", ( (double)( price & SHIFT_MASK ) / ( 1 << SHIFT_AMOUNT ) ) );
std::cout << std::endl;
}
Possible output
====================================================
SHIFT_AMOUNT = 28
SHIFT_MASK = 268435455
0000📍1111111111111111111111111111 268435455 SHIFT_MASK
⛔ no enought bits for integer part holds our example
0100📍0000000000000000000000000000 1073741824 price = 500
1110📍0000000000000000000000000000 3758096384 price += 10
1010📍0000000000000000000000000000 2684354560 price *= 3
0010📍1000000000000000000000000000 671088640 price /= 4
price integer is 2
price fraction is 134217728
price fraction in decimal is 0.500000
====================================================
SHIFT_AMOUNT = 24
SHIFT_MASK = 16777215
00000000📍111111111111111111111111 16777215 SHIFT_MASK
⛔ no enought bits for integer part holds our example
11110100📍000000000000000000000000 4093640704 price = 500
11111110📍000000000000000000000000 4261412864 price += 10
11111010📍000000000000000000000000 4194304000 price *= 3
00111110📍100000000000000000000000 1048576000 price /= 4
price integer is 62
price fraction is 8388608
price fraction in decimal is 0.500000
====================================================
SHIFT_AMOUNT = 16
SHIFT_MASK = 65535
0000000000000000📍1111111111111111 65535 SHIFT_MASK
0000000111110100📍0000000000000000 32768000 price = 500
0000000111111110📍0000000000000000 33423360 price += 10
0000010111111010📍0000000000000000 100270080 price *= 3
0000000101111110📍1000000000000000 25067520 price /= 4
price integer is 382
price fraction is 32768
price fraction in decimal is 0.500000
====================================================
SHIFT_AMOUNT = 8
SHIFT_MASK = 255
000000000000000000000000📍11111111 255 SHIFT_MASK
000000000000000111110100📍00000000 128000 price = 500
000000000000000111111110📍00000000 130560 price += 10
000000000000010111111010📍00000000 391680 price *= 3
000000000000000101111110📍10000000 97920 price /= 4
price integer is 382
price fraction is 128
price fraction in decimal is 0.500000