FTP | CCD | Buscar | Trucos | Trabajo | Foros |
#1
|
|||
|
|||
1+1=3 ?
Hola a todos.
Me dirijo a ustedes porque me pasa lo siguiente en Delphi 7 Professional. Mi problema es con la función format y para ilustrarlo tengo 2 ejemplos muy sencillos. 1º) ejecutar lo siguiente, donde Label1 es un simple TLabel Label1.Caption:=format('%.2n',[1055.885]); -Como resultado el valor obtenido es 1055,89 lo cual es del todo correcto. 2º) probar ahora con lo siguiente donde d es de tipo double. d:=1055.885 Label1.Caption:=format('%.2n',[d]); -El resultado obtenido es 1055,88 lo cual no es correcto. Si lo prueban podrán comprobar esta circunstancia la cual me está generando bastantes problemas dentro de una aplicación que he desarrollado. Personalmente interpreto que es un error que tiene el Delphi; pero me gustaría conocer otras opiniones. Gracias. |
#2
|
||||
|
||||
Ambos resulatdos son correctos: el 5 está a la mitad entre un número y otro de manera que la decisión de a cuál de ellos redondear es totalmente arbitraria. Lo que si es que en estos momentos desconozco el porqué en un caso se toma una decisión y en el otro otra. Posiblemente tiene que ver con la forma en que Delphi interpreta el parámetro cuando lo pasas directamente. Por ejemplo, si en lugar de usar un Double utilizas un Single verás que redondea hacia arriba.
Para solucionar esto usa la funcion SetRoundMode de la unidad math.pas: SetRoundMode(rmUp); // Saludos |
#3
|
||||
|
||||
Seguramente el problema se da por la precision del Double. No tengo delphi a mano para comprobarlo, pero seguramente cuando pones el valor constante, el compilador no lo almacena en un double, sino en otro tipo de dato, que por alguna razón es mas preciso (al menos en este caso).
Si examinas el valor que queda almacenado en la variable d después de hacer la asignación, seguramente no será exactamente 1055.885, sino algo mas parecido a 1055.88499999999 de manera que el redondeo que aplica para la representación textual es correcto. Podes intentar utilizar otro tipo de dato, o bien sumarle un valor infimo que sea suficiente para aplicar un redondeo "correcto". Digamos 0.0001. Esto es una verdadera chapuza, pero realmente funciona. Hasta luego.
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate |
#4
|
|||
|
|||
Gracias a todos por contestar tan rápido. En especial a Román; aunque no me convence mucho lo de que …el 5 está a la mitad entre un número…, he utilizado la función que sugerías SetRoundMode(rmUp) y perfecto.
Gracias de nuevo. |
#5
|
||||
|
||||
Cita:
Distancia entre 1055,885 y 1055,89 = 0,005 // Saludos |
#6
|
|||
|
|||
CUIDADO con QuickReport y poner SetRoundMode(rmUp) .
Al generar unos informes se produce un error stack overflow. Si quito SetRoundMode(rm) todo va perfecto. Asi que estoy como al principio |
#7
|
||||
|
||||
Cita:
Algo que quizá funcione sea restaurar el modo de redondeo en cuanto termines: Código:
var RoundMode: TFPURoundingMode; begin RoundMode := GetRoundMode; SetRoundMode(rmUp); Label1.Caption:=format('%.2n',[d]); SetRoundMode(RoundMode); end; |
#8
|
|||
|
|||
En parte de trucos del club hay una funcion que redondea correctamente al menos ami nunca me falla no recuerdo quien la puso peor la funcion es RoundD revisala ok...... asi te evitas los errores con Quick Report....
__________________
========================== erickpch@yahoo.com "No existe código perfecto, solo más adecuado" (B) :) |
#9
|
|||
|
|||
Olvide desirte que la explicacion al "problema " de redondeo lo encuentras explicado en...
http://www.clubdelphi.com/vertruco.php?id=130 Ahora la funcion que te dije antes no la encuentro en el club, de repente la encontre en otro sitio web, de todas maneras mañana la copio y la pongo en el hilo...
__________________
========================== erickpch@yahoo.com "No existe código perfecto, solo más adecuado" (B) :) |
|
|
|