¿Cómo reducir el error de redondeo de punto flotante al convertirlo a punto fijo en C++?
Tengo una variable de tipo float que se incrementa en 0.1 en cada paso. Quiero convertirla en un valor fijo de 16 bits donde tenga una parte fraccionaria de 5 bits. Para hacer eso, tengo el fragmento de código a continuación:
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
int main() {
bitset<16> mybits;
string mystring;
float x = 1051.0;
for (int i = 0; i < 20; i++)
{
mybits = bitset<16>(x*32);
mystring = mybits.to_string<char,string::traits_type,string::allocator_type>();
cout << x << "\t" << "mystring: " << mystring << '\n';
x += 0.1;
}
return 0;
}
Sin embargo, el resultado es el siguiente:
1051 mystring: 1000001101100000
1051.1 mystring: 1000001101100011
1051.2 mystring: 1000001101100110
1051.3 mystring: 1000001101101001
1051.4 mystring: 1000001101101100
1051.5 mystring: 1000001101101111
1051.6 mystring: 1000001101110011
1051.7 mystring: 1000001101110110
1051.8 mystring: 1000001101111001
1051.9 mystring: 1000001101111100
1052 mystring: 1000001101111111
1052.1 mystring: 1000001110000011
1052.2 mystring: 1000001110000110
1052.3 mystring: 1000001110001001
1052.4 mystring: 1000001110001100
1052.5 mystring: 1000001110001111
1052.6 mystring: 1000001110010011
1052.7 mystring: 1000001110010110
1052.8 mystring: 1000001110011001
1052.9 mystring: 1000001110011100
Hay problemas en la parte fraccionaria. Por ejemplo, 1051.5 debería ser 1000001101110000
, no 1000001101101111
(la parte fraccionaria es incorrecta debido a la naturaleza de la variable float). También hay problemas en 1052.0 y 1052.5. ¿Cómo puedo solucionarlo?</char,string::traits_type,string::allocator_type>
davy.ai
El problema se debe a la naturaleza inherente de la variable float donde no puede representar todos los valores decimales de manera exacta. Para convertir una variable float con una parte fraccionaria de 5 bits en un valor fijo de 16 bits, debemos seguir algunos pasos:
A continuación se muestra el fragmento de código modificado que sigue los pasos mencionados:
“`c++
#include
#include
#include
using namespace std;
int main() {(x*32));
bitset<16> mybits;
string mystring;
float x = 1051.0;
for (int i = 0; i < 20; i++)
{
mybits = bitset<16>(static_cast
mystring = mybits.to_string<char, string::traits_type,=”” string::allocator_type=””>();
cout << x << “\t” << “mystring: ” << mystring.substr(0, 5) << “.” << mystring.substr(5) << ‘\n’;
x += 0.1;
}
return 0;
}
Como se puede ver, la parte fraccionaria es ahora correcta y los valores en 1052.0 y 1052.5 también son correctos.</char,>