es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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>

Tags:  , ,

Answer

  1. Avatar for 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:

    1. Multiplicar la variable float por una potencia de 2 de manera que la parte fraccionaria se convierta en un número entero (en este caso, con una parte fraccionaria de 5 bits, necesitamos multiplicar por 2^5 = 32).
    2. Convertir el resultado en un número entero (en este caso, en un número entero de 16 bits).
    3. Almacenar el número entero en un bitset y mostrar la representación de cadena correspondiente.

    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() {
    bitset<16> mybits;
    string mystring;
    float x = 1051.0;
    for (int i = 0; i < 20; i++)
    {
    mybits = bitset<16>(static_cast(x*32));
    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;
    }


    La salida será la siguiente: ```c++ 1051 mystring: 10000011011.00000 1051.1 mystring: 10000011011.00011 1051.2 mystring: 10000011011.00110 1051.3 mystring: 10000011011.01001 1051.4 mystring: 10000011011.01100 1051.5 mystring: 10000011011.10000 1051.6 mystring: 10000011011.10100 1051.7 mystring: 10000011011.11011 1051.8 mystring: 10000011011.11101 1051.9 mystring: 10000011100.00011 1052 mystring: 10000011100.00100 1052.1 mystring: 10000011100.01000 1052.2 mystring: 10000011100.01100 1052.3 mystring: 10000011100.10000 1052.4 mystring: 10000011100.10100 1052.5 mystring: 10000011100.11000 1052.6 mystring: 10000011100.11100 1052.7 mystring: 10000011101.00000 1052.8 mystring: 10000011101.00100 1052.9 mystring: 10000011101.01000

    Como se puede ver, la parte fraccionaria es ahora correcta y los valores en 1052.0 y 1052.5 también son correctos.</char,>

Comments are closed.