Problemas de redondeo

En general, el trabajo con números flotantes y operaciones matemáticas (tanto complejas como sencillas), puede resultar un auténtico quebradero de cabeza si no prestamos atención. Dependiendo del compilador que utilicemos, las operaciones pueden producir un resultado u otro, ya que los operadores matemáticos básicos están sobrecargados y dicha sobrecarga implica una salida diferente en según qué ocasiones (ej: en un compilador, la suma de un número entero y uno flotante, aunque puede convertirse en un flotante, puede producir una salida de entero, o viceversa) Además de ese peligro, existe la posibilidad del redondeo: aunque por lo general se produce un truncate, no siempre podremos darlo por supuesto…

En Qt me he encontrado, además, con un problema derivado aunque relacionado: los cambios de representación. En el caso del QDoubleSpinBox, realiza un redondeo a los números más cercanos en el traspaso de números: yo almaceno un valor double, lo envío al QDoubleSpinBox y, de repente, me encuentro con un redondeo sobre los decimales que no es deseado. Otro caso: leemos de un archivo un dato double almacenado como un QString y lo transformamos a un valor double, y se produce de nuevo un redondeo.

¿Solución? Almacenar los valores doubles en un QByteArray. Si lo pasamos como un QString, asociamos un QTextStream al QByteArray y a través de él realizamos las modificaciones. En vez de trabajar con valores doubles para la representación, usaremos un QString. Y cuando necesitemos realizar los cálculos, obtendremos el valor double a partir de un QDataStream si es necesario para no perder decimales durante el cambio de representación. Es un poco lioso y no estoy del todo seguro de que el problema sea ese, realmente, pero el caso es que funciona y a veces eso es lo único que importa.

Anuncios

2 pensamientos en “Problemas de redondeo

  1. Hola EdBardo, me puedes poner un ejemplo de lo que has expuesto, porque no consigo pasar los datos de un QDataStream a double y me redondea a unos digitos cuando en realidad deberian llevar minimo 10 y en el caso mio, me pone solo 5
    Ejemplo:
    1.06520 x 1.06520 = 1.11465104
    y en realidad me pone:
    1.114651, pero necesito todos los decimales ya que estoy haciendo un calculo de prestamos y la precisión hace que varie las cuotas mensuales y claro al final del periodo tengo un negativo por las diferencias de redondeo.

    Gracias como siempre!!!

    • Hola, perdona por no responderte antes pero es que he tenido unas semanas horrendas 😀

      He estado buscando el ejemplo que tenía sobre los cambios de formatos y el uso de QDataStream, pero no he conseguido encontrarlo. En principio, QByteArray te permite especificar la precisión de un número cuando lo introduces mediante el método setNum ( ); pero, utilizando un QTextStream para pasar la información desde un archivo de texto al QByteArray, no empleamos el método setNum sino que directamente escribimos en el QByteArray desde una cadena de caracteres (p.e, para leer información de un archivo de texto).

      Ojo, esto sólo sirve para intentar que, al introducir los datos, no se produzcan pérdidas de información por redondeos extraños. A la hora de presentar los datos al usuario, también se producen redondeos; los cálculos sobre valores doubles dentro del sistema no pierden información ya que operan con todos los bits, pero al cambiar de formato es donde vemos las cosas extrañas. Mi consejo es: para convertir los datos doubles a cadenas de caracteres y presentarlos al usuario, emplea el método setNum de QString y genera una cadena de caracteres a partir del valor double resultante ( )

      ¡Un saludo!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s