Думаю, я понимаю, что происходит при преобразовании значений в представление с фиксированной запятой с помощью следующего кода. Используйте 2-битную для целой части и 30-битную для дробной части числа, чтобы мы получили результирующий диапазон от -2.0
до 1.999999999
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
unsigned int transformForTransfer(double value){
int integer;
unsigned int shiftedInteger;
double fraction;
if(value >= 0){
integer = (int32_t)value;
fraction = value - integer;
shiftedInteger = (unsigned int)(integer << 30);
}
else{
integer = -2;
fraction = 2.0 + value;
shiftedInteger = 0x80000000;
}
auto fractionPart = (unsigned int)round(fraction * std::pow(2, 30));
std::cout << "fraction part : " << std::bitset<sizeof(fractionPart) * 8>(fractionPart) << std::endl;
std::cout << "integer part : " << std::bitset<sizeof(integer) * 8>(integer) << std::endl;
auto result = (shiftedInteger | fractionPart);
auto bits = std::bitset<sizeof(result) * 8>(result).to_string();
std::cout << "value bits unsigned int: " << bits << std::endl;
return result;
}
Но зачем использовать этот простой подход:
unsigned int doubleToTransfer(double value)
{
return (unsigned int)(round(value * std::pow(2, 30)));
}
приведет к тому же результату:
int demoInt = -2000000000;
double demo;
while (demoInt < 1999999999){
demoInt += 1;
demo = demoInt * 1E-09;
if(transformForTransfer(demo) != doubleToTransfer(demo)){
// never reached
std::cout << " != " << demo << std::endl;
}
}