Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo Hace 1 Semana
Avatar de hgiacobone
hgiacobone hgiacobone is offline
Miembro
 
Registrado: may 2003
Ubicación: La Plata, Bs. As., Argentina
Posts: 162
Poder: 15
hgiacobone Va por buen camino
Arrow Problema decimales en 64bits

Bueno, si aun no lo han sufrido estén atentos.
Transmito nuestra reciente experiencia.

Nosotros utilizamos XE-10.2 Tokyo v.25.0.263x pero aplica en cualquier XE compilado en 64 bits

Observen este ejemplo:
Código Delphi [-]
var
  F: Single;
begin
  F := 0.1;
  if F = 0.1 then
    ShowMessage('equal')
  else
    ShowMessage('not equal');
end;
La pregunta del millón es: ¿cuál será la respuesta de salida?

Respuesta: "not equal"

Aquí un muy buen artículo, totalmente recomendado, con la explicación del problema: http://rvelthuis.de/articles/articles-floats.html


Por ejemplo, a nosotros nos acaba de pasar con, nada menos, que la emisión de comprobantes de ventas y el cálculo de percepciones de ingresos brutos.
Algo sencillo:
Código Delphi [-]
function Parte_Entera(f: single): integer;
begin
  Result:= int( f ); 
end
Si el valor de entrada es por ejemplo "2946" sin ningún decimal, la función anterior devolverá "2945" y, si se trata de dinero es un Euro menos y si se trata de enviar un rover a Marte con suerte lo aterrizamos en Urano

Aquí, http://docwiki.embarcadero.com/RADSt...int_Arithmetic la gente de Embarcadero te ilustra como ellos se "lavan las manos" y en síntesis te dicen que el problema puede ser tu diseño, por pensar que una variable Single o Double de valor "0,25" en realidad por ejemplo puede llegar a ser "0.2499999999999999999999" y que obviamente TODO el mundo lo sabe menos vos

...empiezo a extrañar mucho al querido Clipper 5.01


Ahora bien, a modo de resumen, utilizando XE compilado en 64 bits, el tipo Double pasa a ser interpretada como Extended y no solo eso, todo el manejo de variables internamente XE lo hace convertido a Extended.
Por consiguiente, como lo recomendable es no ir cambiando entre tipos para que nos se "pierdan decimales" entre conversiones, lo recomendado es manejar todo en Extended, aun cuando necesites operar solo con 2 decimales

Sin embrago, en operaciones tradicionales de suma, resta y multiplicación, los resultados parecen mantenerse bien aun cuando sea entre tipos diferentes.
Las divisiones, exponenciales y otros cómputos como el uso de RoundTo() que puedan generar varios decimales ya presentan algún problema.

En el caso de REDONDEO, nuestra solución fue utilizar una función propia, basada en una antigua de Delphi 7 y "forzando" a utiliza el redondeo hacia arriba:
Código Delphi [-]
Function RoundD(x: Extended; d: Integer): Extended;
var
 n, f: Extended;
 i: integer;
 OldRM: TRoundingMode;
begin
  n := Power(10, d);
  x := x * n;
{--“Bankers rounding”--->Result := ( (Int(x) + Int(Frac(x)*2) ) / n);}

  OldRM := GetRoundMode;
  try
    SetRoundMode(rmUp);

    i := Trunc(X);
    f := ((x - i) + 0.00000001) ;
    if f>=1
     then Result := (x / n )   {cuando es un entero}
     else Result := ( (Int(x) + Int((f*2)) ) / n );

  finally
    SetRoundMode(OldRM);
  end;
end;

Suerte amigos!
__________________
Gracias de antemano por vuestra ayuda.
·.:*:.·Yako·.:*:.·
Responder Con Cita
  #2  
Antiguo Hace 1 Semana
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 27.698
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por hgiacobone Ver Mensaje
... la gente de Embarcadero te ilustra como ellos se "lavan las manos" y en síntesis te dicen que el problema puede ser tu diseño, por pensar que una variable Single o Double de valor "0,25" en realidad por ejemplo puede llegar a ser "0.2499999999999999999999" y que obviamente TODO el mundo lo sabe menos vos

Es que es así, realmente no tiene nada que ver con delphi, es un tema que hemos tratado en diversas ocasiones.
Responder Con Cita
  #3  
Antiguo Hace 1 Semana
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 9.875
Poder: 27
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.
Cita:
Empezado por Casimiro Notevi Ver Mensaje
[/i]Es que es así, realmente no tiene nada que ver con delphi, es un tema que hemos tratado en diversas ocasiones.
Así es, aquí hay una: redondear decimas de un float como excel.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #4  
Antiguo Hace 1 Semana
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 27.698
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por ecfisa Ver Mensaje
Hola.
Así es, aquí hay una: redondear decimas de un float como excel.
Saludos
Ese fue un buen hilo sobre el tema
Responder Con Cita
  #5  
Antiguo Hace 1 Semana
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.834
Poder: 9
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Por supuesto que es un problema del programador, y no de Embarcadero. No se pueden comparar numeros de coma flotante por igualdad, y el que te diga lo contrario, está mintiendo o no tiene idea del tema. Los numeros flotantes se pueden comparar "aproximadamente". Esto es intrinseco a como se representan estos numeros, basicamente, hay números que no se pueden representar exactamente, entonces por eso siempre se "redondea" o se "aproximan".

Si necesitas precision, y usas numeros de aritmetica flotante, vas mal. Deberias usar un tipo de datos de los que se conoce como "fixed". En Delphi, ese tipo de datos se llama Currency. Desde todos los lenguajes de programacion, hasta las bases de datos, contemplan este tipo de datos (puede ser llamado currency, money, fixedfloat, etc). Basicamente funciona como un entero de 64bits (con signo), pero del cual se interpretan los ultimos 4 digitos del numero como los decimales; en la practica, no creo que necesites mas de 4 decimales para manejar dinero. En Delphi creo que existe otra alternativa, el Binary Coded Decimal (BCD), pero nunca lo he usado y no puedo opinar

Te recomiendo que leas esto http://floating-point-gui.de/
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
problema con decimales largos darkbits Varios 11 24-06-2015 02:21:36
Problema con decimales (componente rx) look OOP 16 15-12-2011 20:51:26
problema con el registro de decimales Choclito Varios 7 29-08-2007 03:19:40
Problema con los decimales anam.soria Firebird e Interbase 1 07-03-2007 19:43:39
Problema con obtencion de decimales onlytk Varios 5 18-07-2006 03:48:00


La franja horaria es GMT +2. Ahora son las 21:42:00.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi