none
Problema con decimales en Visual Studio RRS feed

  • Pregunta

  • Hola, recientemente me surgió un problema al estar programando, y es que algunos decimales se imprimen mal en pantalla, para que me entiendan mejor, digamos que quiero imprimir en pantalla en número 0.2588, y escribo la linea de código, entonces en vez de que me salga en pantalla 0.2588 me sale el número 0.2587999999, en otras palabras, no pone bien los decimales, los cambia por otros, ya comprobé que no es mi método el que esta mal, pues me puse a realizar operaciones sencillas de resta y división tanto en consola como en Windows Form y sigue saliendo ese error, si alguien me pudiera ayudar le estaría muy agradecido.  
    martes, 24 de octubre de 2017 6:23

Respuestas

  • Con independencia de que se pueda encontrar uno u otro truquillo para solucionarlo (como por ejemplo hacer un redondeo), es importante que comprendas por qué sucede ese "cambio" de decimales, porque al entenderlo te ahorrarás muchos quebraderos de cabeza en el futuro.

    Internamente, el ordenador no maneja números en base 10, sino en base 2. Se da la circunstancia de que ciertos números que en base 10 tienen un número finito de decimales, como tu 0.2588, sin embargo en base 2 tienen INFINITOS decimales. Evidentemente, el espacio que utiliza el ordenador para almacenarlos no es infinito (por ejemplo, se usan 4 bytes si declaras el número como float y 8 si lo declaras como double). Al guardar en esos bytes el número en base 2, se desprecian los decimales que no "caben" en ese almacenamiento. Cuando luego vuelves a convertir el número a base 10, lógicamente te sale un valor ligeramente distinto al que guardaste, debido a esos decimales que se perdieron.

    Por eso los tipos de datos float y double se llaman números imprecisos, porque no salvan con exactitud el número que asignaste. Solo se deben usar para almacenar datos que son inherentemente imprecisos, como por ejemplo el resultado de hacer una medición física, donde te da igual que se pierdan las milmillonésimas porque en cualquier caso la cifra que se midió tenía una precisión muchísimo menor que esa.

    Cuando se necesita exactitud, hay que uras tipos de datos precisos en lugar de imprecisos. En .Net tienes el System.Decimal, que usa otro tipo de codificación interna para que no se requiera pasar decimales a base 2. Con este tipo de dato no perderás los decimales.

    [Editado:] Nótese que esto no es un "problema de Visual Studio" como decía el título de la pregunta. El mismo problema exactamente se presenta con cualquier entorno o lenguaje informático que represente los números de coma flotante en base 2.
    martes, 24 de octubre de 2017 13:31
    Moderador

Todas las respuestas

  • Buenas,

    Para evitar el problema, podrías usar un Math.Round para especificar que quieres solo 4 digitos

    int nDecimales = 4;
    decimal tuVariable = Math.Round(tu operación,nDecimales) ; 

    Nos comentas si tienes dudas. 

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:

    martes, 24 de octubre de 2017 7:45
  • Con independencia de que se pueda encontrar uno u otro truquillo para solucionarlo (como por ejemplo hacer un redondeo), es importante que comprendas por qué sucede ese "cambio" de decimales, porque al entenderlo te ahorrarás muchos quebraderos de cabeza en el futuro.

    Internamente, el ordenador no maneja números en base 10, sino en base 2. Se da la circunstancia de que ciertos números que en base 10 tienen un número finito de decimales, como tu 0.2588, sin embargo en base 2 tienen INFINITOS decimales. Evidentemente, el espacio que utiliza el ordenador para almacenarlos no es infinito (por ejemplo, se usan 4 bytes si declaras el número como float y 8 si lo declaras como double). Al guardar en esos bytes el número en base 2, se desprecian los decimales que no "caben" en ese almacenamiento. Cuando luego vuelves a convertir el número a base 10, lógicamente te sale un valor ligeramente distinto al que guardaste, debido a esos decimales que se perdieron.

    Por eso los tipos de datos float y double se llaman números imprecisos, porque no salvan con exactitud el número que asignaste. Solo se deben usar para almacenar datos que son inherentemente imprecisos, como por ejemplo el resultado de hacer una medición física, donde te da igual que se pierdan las milmillonésimas porque en cualquier caso la cifra que se midió tenía una precisión muchísimo menor que esa.

    Cuando se necesita exactitud, hay que uras tipos de datos precisos en lugar de imprecisos. En .Net tienes el System.Decimal, que usa otro tipo de codificación interna para que no se requiera pasar decimales a base 2. Con este tipo de dato no perderás los decimales.

    [Editado:] Nótese que esto no es un "problema de Visual Studio" como decía el título de la pregunta. El mismo problema exactamente se presenta con cualquier entorno o lenguaje informático que represente los números de coma flotante en base 2.
    martes, 24 de octubre de 2017 13:31
    Moderador
  • Gracias por la información, he hecho lo que me has indicado y se ha solucionado mi problema, ahora ya puedo poner los números con exactitud, gracias
    martes, 24 de octubre de 2017 17:30