FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Problema con redondeos en doubles
Hola. Tengo un problema con los redondeos cuando la variable es de tipo double. Cuando es extended va bien. El problema se reproduce tanto en Delphi 5 como en Delphi 2010, haciendo la misma prueba en ambos.
No sé de donde viene el problema, pero me gustaría determinar si lo mejor es usar siempre extended. Este problema se agudiza cuando tienes dos doubles y comparas, diciéndote que son diferentes cuando en realidad deberían ser iguales. Os pongo el código fuente para que lo veáis: a) Ejemplo de rendondeo por pantalla en un bucle. Tengo en pantalla un botón y dos campos memo. Código:
procedure TForm1.Button1Click(Sender: TObject); var pp,pp2:Double; kk,kk2:Extended; j:smallint; begin { case RadioGroup1.ItemIndex of 0:Math.SetRoundMode(rmNearest); 1:Math.SetRoundMode(rmUp); 2:Math.SetRoundMode(rmDown); 3:Math.SetRoundMode(rmTruncate); end; } memo1.Lines.Clear; memo2.lines.clear; pp:=0.005; kk:=0.005; pp2:=-0.005; kk2:=-0.005; for j := 1 to 100 do begin pp:=pp+0.01; kk:=kk+0.01; pp2:=pp2-0.01; kk2:=kk2-0.01; if formatfloat('0.00',pp)=formatfloat('0.00',kk) then memo1.Lines.Add(floattostr(pp)+' | '+formatfloat('0.00',pp)+' | '+formatfloat('0.00',kk)+' | '+floattostr(kk)) else memo1.Lines.Add(floattostr(pp)+' | '+formatfloat('0.00',pp)+' | '+formatfloat('0.00',kk)+' | '+floattostr(kk)+' <--- error'); if formatfloat('0.00',pp2)=formatfloat('0.00',kk2) then memo2.Lines.Add(floattostr(pp2)+' | '+formatfloat('0.00',pp2)+' | '+formatfloat('0.00',kk2)+' | '+floattostr(kk2)) else memo2.Lines.Add(floattostr(pp2)+' | '+formatfloat('0.00',pp2)+' | '+formatfloat('0.00',kk2)+' | '+floattostr(kk2)+' <--- error'); end; end; Código:
MEMO1: 0,015 | 0,01 | 0,02 | 0,015 <--- error 0,025 | 0,02 | 0,03 | 0,025 <--- error 0,035 | 0,03 | 0,04 | 0,035 <--- error 0,045 | 0,04 | 0,05 | 0,045 <--- error 0,055 | 0,06 | 0,06 | 0,055 0,065 | 0,07 | 0,07 | 0,065 0,075 | 0,07 | 0,08 | 0,075 <--- error 0,085 | 0,08 | 0,09 | 0,085 <--- error 0,095 | 0,09 | 0,10 | 0,095 <--- error 0,105 | 0,10 | 0,11 | 0,105 <--- error 0,115 | 0,11 | 0,12 | 0,115 <--- error 0,125 | 0,12 | 0,13 | 0,125 <--- error 0,135 | 0,13 | 0,14 | 0,135 <--- error 0,145 | 0,14 | 0,15 | 0,145 <--- error 0,155 | 0,15 | 0,16 | 0,155 <--- error 0,165 | 0,17 | 0,17 | 0,165 0,175 | 0,18 | 0,18 | 0,175 0,185 | 0,19 | 0,19 | 0,185 0,195 | 0,20 | 0,20 | 0,195 0,205 | 0,21 | 0,21 | 0,205 0,215 | 0,22 | 0,22 | 0,215 0,225 | 0,23 | 0,23 | 0,225 0,235 | 0,24 | 0,24 | 0,235 0,245 | 0,25 | 0,25 | 0,245 0,255 | 0,26 | 0,26 | 0,255 0,265 | 0,27 | 0,27 | 0,265 0,275 | 0,28 | 0,28 | 0,275 0,285 | 0,29 | 0,29 | 0,285 0,295 | 0,30 | 0,30 | 0,295 0,305 | 0,31 | 0,31 | 0,305 0,315 | 0,32 | 0,32 | 0,315 0,325 | 0,33 | 0,33 | 0,325 0,335 | 0,34 | 0,34 | 0,335 0,345 | 0,35 | 0,35 | 0,345 0,355 | 0,36 | 0,36 | 0,355 0,365 | 0,37 | 0,37 | 0,365 0,375 | 0,38 | 0,38 | 0,375 0,385 | 0,39 | 0,39 | 0,385 0,395 | 0,40 | 0,40 | 0,395 0,405 | 0,41 | 0,41 | 0,405 0,415 | 0,42 | 0,42 | 0,415 0,425 | 0,43 | 0,43 | 0,425 0,435 | 0,44 | 0,44 | 0,435 0,445 | 0,45 | 0,45 | 0,445 0,455 | 0,46 | 0,46 | 0,455 0,465 | 0,47 | 0,47 | 0,465 0,475 | 0,48 | 0,48 | 0,475 0,485 | 0,49 | 0,49 | 0,485 0,495 | 0,50 | 0,50 | 0,495 0,505 | 0,51 | 0,51 | 0,505 0,515 | 0,52 | 0,52 | 0,515 0,525 | 0,53 | 0,53 | 0,525 0,535 | 0,54 | 0,54 | 0,535 0,545 | 0,55 | 0,55 | 0,545 0,555 | 0,56 | 0,56 | 0,555 0,565 | 0,57 | 0,57 | 0,565 0,575 | 0,58 | 0,58 | 0,575 0,585 | 0,59 | 0,59 | 0,585 0,595 | 0,60 | 0,60 | 0,595 0,605 | 0,61 | 0,61 | 0,605 0,615 | 0,62 | 0,62 | 0,615 0,625 | 0,63 | 0,63 | 0,625 0,635 | 0,64 | 0,64 | 0,635 0,645 | 0,65 | 0,65 | 0,645 0,655 | 0,66 | 0,66 | 0,655 0,665 | 0,67 | 0,67 | 0,665 0,675 | 0,68 | 0,68 | 0,675 0,685 | 0,69 | 0,69 | 0,685 0,695 | 0,70 | 0,70 | 0,695 0,705 | 0,71 | 0,71 | 0,705 0,715 | 0,72 | 0,72 | 0,715 0,725 | 0,73 | 0,73 | 0,725 0,735 | 0,74 | 0,74 | 0,735 0,745 | 0,75 | 0,75 | 0,745 0,755 | 0,76 | 0,76 | 0,755 0,765 | 0,77 | 0,77 | 0,765 0,775 | 0,78 | 0,78 | 0,775 0,785 | 0,79 | 0,79 | 0,785 0,795 | 0,80 | 0,80 | 0,795 0,805 | 0,81 | 0,81 | 0,805 0,815000000000001 | 0,82 | 0,82 | 0,815 0,825000000000001 | 0,83 | 0,83 | 0,825 0,835000000000001 | 0,84 | 0,84 | 0,835 0,845000000000001 | 0,85 | 0,85 | 0,845 0,855000000000001 | 0,86 | 0,86 | 0,855 0,865000000000001 | 0,87 | 0,87 | 0,865 0,875000000000001 | 0,88 | 0,88 | 0,875 0,885000000000001 | 0,89 | 0,89 | 0,885 0,895000000000001 | 0,90 | 0,90 | 0,895 0,905000000000001 | 0,91 | 0,91 | 0,905 0,915000000000001 | 0,92 | 0,92 | 0,915 0,925000000000001 | 0,93 | 0,92 | 0,925 <--- error 0,935000000000001 | 0,94 | 0,93 | 0,935 <--- error 0,945000000000001 | 0,95 | 0,94 | 0,945 <--- error 0,955000000000001 | 0,96 | 0,95 | 0,955 <--- error 0,965000000000001 | 0,97 | 0,96 | 0,965 <--- error 0,975000000000001 | 0,98 | 0,97 | 0,975 <--- error 0,985000000000001 | 0,99 | 0,98 | 0,985 <--- error 0,995000000000001 | 1,00 | 0,99 | 0,995 <--- error 1,005 | 1,01 | 1,01 | 1,005 Código:
MEMO2: -0,015 | -0,01 | -0,02 | -0,015 <--- error -0,025 | -0,02 | -0,03 | -0,025 <--- error -0,035 | -0,03 | -0,04 | -0,035 <--- error -0,045 | -0,04 | -0,05 | -0,045 <--- error -0,055 | -0,06 | -0,06 | -0,055 -0,065 | -0,07 | -0,07 | -0,065 -0,075 | -0,07 | -0,08 | -0,075 <--- error -0,085 | -0,08 | -0,09 | -0,085 <--- error -0,095 | -0,09 | -0,10 | -0,095 <--- error -0,105 | -0,10 | -0,11 | -0,105 <--- error -0,115 | -0,11 | -0,12 | -0,115 <--- error -0,125 | -0,12 | -0,13 | -0,125 <--- error -0,135 | -0,13 | -0,14 | -0,135 <--- error -0,145 | -0,14 | -0,15 | -0,145 <--- error -0,155 | -0,15 | -0,16 | -0,155 <--- error -0,165 | -0,17 | -0,17 | -0,165 -0,175 | -0,18 | -0,18 | -0,175 -0,185 | -0,19 | -0,19 | -0,185 -0,195 | -0,20 | -0,20 | -0,195 -0,205 | -0,21 | -0,21 | -0,205 -0,215 | -0,22 | -0,22 | -0,215 -0,225 | -0,23 | -0,23 | -0,225 -0,235 | -0,24 | -0,24 | -0,235 -0,245 | -0,25 | -0,25 | -0,245 -0,255 | -0,26 | -0,26 | -0,255 -0,265 | -0,27 | -0,27 | -0,265 -0,275 | -0,28 | -0,28 | -0,275 -0,285 | -0,29 | -0,29 | -0,285 -0,295 | -0,30 | -0,30 | -0,295 -0,305 | -0,31 | -0,31 | -0,305 -0,315 | -0,32 | -0,32 | -0,315 -0,325 | -0,33 | -0,33 | -0,325 -0,335 | -0,34 | -0,34 | -0,335 -0,345 | -0,35 | -0,35 | -0,345 -0,355 | -0,36 | -0,36 | -0,355 -0,365 | -0,37 | -0,37 | -0,365 -0,375 | -0,38 | -0,38 | -0,375 -0,385 | -0,39 | -0,39 | -0,385 -0,395 | -0,40 | -0,40 | -0,395 -0,405 | -0,41 | -0,41 | -0,405 -0,415 | -0,42 | -0,42 | -0,415 -0,425 | -0,43 | -0,43 | -0,425 -0,435 | -0,44 | -0,44 | -0,435 -0,445 | -0,45 | -0,45 | -0,445 -0,455 | -0,46 | -0,46 | -0,455 -0,465 | -0,47 | -0,47 | -0,465 -0,475 | -0,48 | -0,48 | -0,475 -0,485 | -0,49 | -0,49 | -0,485 -0,495 | -0,50 | -0,50 | -0,495 -0,505 | -0,51 | -0,51 | -0,505 -0,515 | -0,52 | -0,52 | -0,515 -0,525 | -0,53 | -0,53 | -0,525 -0,535 | -0,54 | -0,54 | -0,535 -0,545 | -0,55 | -0,55 | -0,545 -0,555 | -0,56 | -0,56 | -0,555 -0,565 | -0,57 | -0,57 | -0,565 -0,575 | -0,58 | -0,58 | -0,575 -0,585 | -0,59 | -0,59 | -0,585 -0,595 | -0,60 | -0,60 | -0,595 -0,605 | -0,61 | -0,61 | -0,605 -0,615 | -0,62 | -0,62 | -0,615 -0,625 | -0,63 | -0,63 | -0,625 -0,635 | -0,64 | -0,64 | -0,635 -0,645 | -0,65 | -0,65 | -0,645 -0,655 | -0,66 | -0,66 | -0,655 -0,665 | -0,67 | -0,67 | -0,665 -0,675 | -0,68 | -0,68 | -0,675 -0,685 | -0,69 | -0,69 | -0,685 -0,695 | -0,70 | -0,70 | -0,695 -0,705 | -0,71 | -0,71 | -0,705 -0,715 | -0,72 | -0,72 | -0,715 -0,725 | -0,73 | -0,73 | -0,725 -0,735 | -0,74 | -0,74 | -0,735 -0,745 | -0,75 | -0,75 | -0,745 -0,755 | -0,76 | -0,76 | -0,755 -0,765 | -0,77 | -0,77 | -0,765 -0,775 | -0,78 | -0,78 | -0,775 -0,785 | -0,79 | -0,79 | -0,785 -0,795 | -0,80 | -0,80 | -0,795 -0,805 | -0,81 | -0,81 | -0,805 -0,815000000000001 | -0,82 | -0,82 | -0,815 -0,825000000000001 | -0,83 | -0,83 | -0,825 -0,835000000000001 | -0,84 | -0,84 | -0,835 -0,845000000000001 | -0,85 | -0,85 | -0,845 -0,855000000000001 | -0,86 | -0,86 | -0,855 -0,865000000000001 | -0,87 | -0,87 | -0,865 -0,875000000000001 | -0,88 | -0,88 | -0,875 -0,885000000000001 | -0,89 | -0,89 | -0,885 -0,895000000000001 | -0,90 | -0,90 | -0,895 -0,905000000000001 | -0,91 | -0,91 | -0,905 -0,915000000000001 | -0,92 | -0,92 | -0,915 -0,925000000000001 | -0,93 | -0,92 | -0,925 <--- error -0,935000000000001 | -0,94 | -0,93 | -0,935 <--- error -0,945000000000001 | -0,95 | -0,94 | -0,945 <--- error -0,955000000000001 | -0,96 | -0,95 | -0,955 <--- error -0,965000000000001 | -0,97 | -0,96 | -0,965 <--- error -0,975000000000001 | -0,98 | -0,97 | -0,975 <--- error -0,985000000000001 | -0,99 | -0,98 | -0,985 <--- error -0,995000000000001 | -1,00 | -0,99 | -0,995 <--- error -1,005 | -1,01 | -1,01 | -1,005 Pero ahora, visto lo visto, pongo otro botón en la pantalla y un label y asocio al botón el código siguiente: Código:
procedure TForm1.Button2Click(Sender: TObject); var pp,kk:double; begin pp:=0.805; kk:=0.815; pp:=pp+0.01; if pp=kk then label1.caption:='iguales' else label1.caption:='distintos: ' + FloatToStr(pp)+ ' <> ' + floattostr(kk); end; Algo estoy haciendo mal ... esto no puede ser así ... |
#2
|
||||
|
||||
__________________
Daniel Didriksen Guía de estilo - Uso de las etiquetas - La otra guía de estilo .... |
#3
|
||||
|
||||
Yo recomendaría la lectura del artículo What Every Computer Scientist Should Know About Floating-Point Arithmetic.
Podrá ser bastante denso y aburrido, sobre todo sabiendo que está en inglés y a algunos no nos fascina ese idioma, pero señala y aborda muchas cuestiones técnicas sobre la aritemética de punto flotante. Más en puntual sobre la comparación de números de punto flotante el artículo Comparing Floating Point Number aclara muchas cosas. He colocado el enlace a la versión actualizada (a este año). Ya con eso te puedes hacer una idea de porque es una muy mala idea hacer comparaciones tan directas como lo hacemos de toda la vida con los números enteros Saludos, |
#4
|
|||
|
|||
Ok. Gracias por la información.
Utilizaré la función para comparar valores disponible en la unit math y ya está. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
sumar valores nulos con doubles sql. | ingabraham | Varios | 5 | 14-12-2010 23:27:10 |
Problema con redondeos en campos Money | river_1 | SQL | 3 | 16-06-2010 01:59:34 |
Redondeos y no redondeos | vivamotos | C++ Builder | 6 | 12-06-2010 00:29:48 |
Redondeos con Firebird 2.0 | Jose_T | Firebird e Interbase | 12 | 19-01-2007 19:57:02 |
Problemas con Redondeos | AGAG4 | Varios | 4 | 14-11-2005 23:38:44 |
|