Domingo 22 de Diciembre de 2024, 13:46
SoloCodigo
Bienvenido(a),
Visitante
. Por favor,
ingresa
o
regístrate
.
¿Perdiste tu
email de activación?
Inicio
Foros
Chat
Ayuda
Buscar
Ingresar
Registrarse
SoloCodigo
»
Foros
»
CLR: .Net / Mono / Boo / Otros CLR
»
C#
(Moderador:
ProfesorX
) »
Precisión
« anterior
próximo »
Imprimir
Páginas: [
1
]
Autor
Tema: Precisión (Leído 1467 veces)
E.Baley
Miembro activo
Mensajes: 44
Precisión
«
en:
Viernes 29 de Agosto de 2008, 10:37 »
0
Hola amigos, a ver si me podeis ayudar en una duda que me trae de cabeza.
En algún lugar de un programa uso listas de valores en coma flotante. Puesto que cada valor sólo usa como máximo cinco posiciones decimales, me dispongo a usar el tipo que menos recursos necesite, a elegir entre Decimal (16 bytes), Double (8 bytes) y Float (4 bytes). Evidentemente el Float es el más económico en recursos, sobre todo si usamos listas con miles de Floats dentro.
Sin embargo, cuando realizo operaciones en los valores, la precisión se va degradando de forma que siempre obtengo decimales en posiciones que no deberían estar. Para hacerme entender, 0.0075d + 0.0025d debería ser 0.01 sin embargo me sale un número con muchos más decimales que se aproxima mucho al resultado correcto.
El mismo error me ocurre con los Float, únicamente trabajando con Decimal me realiza las operaciones correctamente, pero entonces uso 16 bytes en vez de 4 (4 veces más de espacio en memoria !!).
A modo de ejemplo:
Código: Text
static void Main(string[] args) {
List<float> listaF = new List<float>();
float f1 = 0.0075F;
float incrementoF = 0.0025F;
for (int i = 0; i < 100; i++) {
// Esto se degrada con el paso de las iteraciones, y adquiere cada vez más decimales
f1 = f1 + incrementoF;
// Tengo que hacer esto para que pierda los decimales que no interesan
//f1 = Single.Parse(f1.ToString("F4"));
listaF.Add(f1);
Console.WriteLine("Posición {0}: {1}", i, f1);
}
//Poner un punto de interrupción aquí, y mirar la lista en la ventana de "Variables locales" del debugger
Console.ReadLine();
}
Bueno, veréis que la única solución que se me ocurre es truncar los decimales sobrantes convirtiendo a string y volviendo a parsear esa cadena, una solución bastante chapucera que además es poco eficiente. ¿ Cómo debo hacer para que me sume correctamente, sin decimales fantasma ?
gracias.
Tweet
ProfesorX
Moderador
Mensajes: 796
Nacionalidad:
Re: Precisión
«
Respuesta #1 en:
Viernes 29 de Agosto de 2008, 19:53 »
0
Pues esa es la solucion, usar decimal en lugar de float
La precision de los float es asi, no puedes cambiarla, y aunque trunques, el resultado nunca sera exacto.
Lo mejor es decimal,, ya que es un formato que tiene precision hasta 28 digitos.
La pregunta que debes hacerte no es ¿Cuanto espacio me ocupara? sino ¿Necesito alta precision, porque requiero guardar valores con varios decimale? Si la respuesta es afirmativa, entonces debes usar decimal.
NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================
E.Baley
Miembro activo
Mensajes: 44
Re: Precisión
«
Respuesta #2 en:
Viernes 29 de Agosto de 2008, 20:07 »
0
Gracias profe
Definitivamente, parece que usar el tipo Decimal es a la vez la solución y el problema.
Respondiendo a tu pregunta "¿ Necesito alta precision, porque requiero guardar valores con varios decimales ?"
La respuesta es "no" , no necesito alta precisión (todos los valores deben llevar como máximo 5 decimales). Por tanto, usaré el tipo Float.
Sin embargo, al usar el Float, cualquier cálculo sobre ellos (por sencillo que sea) da un resultado erróneo.
Otra solución que encontré es usar Math.Round(unFloat, 5) para redondear al 5º decimal, después de cada operación.
Ahora debo elegir entre tiempo de proceso y uso de memoria.
gracias en cualquier caso.
psikotic
Nuevo Miembro
Mensajes: 12
Re: Precisión
«
Respuesta #3 en:
Lunes 6 de Octubre de 2008, 18:32 »
0
En realidad se debe a la forma en que son representados los numeros de punto flotante en .NET y en casi cualquier compilador de otros lenguajes se tiene el mismo detalle, si requieres hacer calculos precisos usa Decimal, si no basta con mostrar tu informacion con un Formatter el que usaste "F4", solo usalo a la hora de mostrar al usuario:
Console.WriteLine("Posición {0}: {1:F4}", i, f1);
Mas info en
Código: Text
docs.sun.com/source/806-3568/ncg_goldberg.html
Imprimir
Páginas: [
1
]
« anterior
próximo »
SoloCodigo
»
Foros
»
CLR: .Net / Mono / Boo / Otros CLR
»
C#
(Moderador:
ProfesorX
) »
Precisión