Club Delphi  
    Paypal   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

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 30-03-2012
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.610
Poder: 32
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Se quitan los ceros al multiplicar y dividir Variant BCD (TFmtBCDField) y Currency

Hola, para compartirles esto y de paso indagar más.

Me topé con cierto error de cálculo matemático en algo que estoy programando. Cuando el resultado tiene que ser 50, me arroja 5, cuando tiene que ser 800, me arroja 8, pero si tiene que ser 51 u 802, entonces sí lo respeta:
Código:
Debe ser  Resulta
   50         5 (incorrecto)
  800         8 (incorrecto)
   51        51 (correcto)
  802       802 (correcto)
En pocas palabras, elimina los ceros significativos a la derecha del número. La operación matemática que realizo es por demás simple de entender:

X = (A * B) / B

Siendo A el número 50, 800, 51, 802, etcétera, y B una cantidad indeterminada. Si Multiplico A por B y al resultado le hago la operación inversa (dividirlo entre B), el resultado final será nuevamente en A, ¿cierto? Pero no sucede así en la versión 7 de Delphi cuando:
  • A es un entero que termina en 0 de tipo Currency,
  • la primera aparición de B es de tipo variante BCD,
  • la segunda aparición de B es de tipo Currency,
  • y toda la operación se hace en la misma sentencia
Es decir:
Código Delphi [-]
X := (A_Currency * B_VariantBCD) / B_Currency

Lo he probado en Delphi 2007 también, con la fortuna de que ahí no ocurre el error de cálculo, por lo cual creo que se trata de un defecto corregido en alguna de las versiones posteriores a la 7.

Les agradecería si me ayudan ha probar este sencillo código con la versión de la que ustedes dispongan:
Código Delphi [-]
Uses
  FmtBCD;

procedure TForm1.Button1Click(Sender: TObject);
Var
  C1, C2, C3 :Currency;
  V :Variant;
begin
  C1 := 50;
  C2 := 149.88;
  V := VarFMTBcdCreate (149.88);

  // (50 * 149.88) / 149.88 = 50

  C3 := (C1 * V) / C2;  // ¡Resulta 5!
  ShowMessage (CurrToStr (C3));

  // Una forma de evitar el problema es usar molde de tipo sobre el Variant
  C3 := (C1 * Currency (V)) / C2;  // Correcto, resulta 50
  ShowMessage (CurrToStr (C3));

  // Como la primera prueba pero con 51 en lugar de 50
  C1 := 51;
  C3 := (C1 * V) / C2;  // Resulta 51, como debe ser
  ShowMessage (CurrToStr (C3));

  // Como la primera prueba pero con 800
  C1 := 800;
  C3 := (C1 * V) / C2;  // ¡Resulta 8!
  ShowMessage (CurrToStr (C3));

  // Como la primera prueba pero con 802
  C1 := 802;
  C3 := (C1 * V) / C2;  // Resulta 802, como debe ser
  ShowMessage (CurrToStr (C3));
end;
Desconozco si este problema fue reportado en su momento, ya que no tuve suerte de encontrar información sobre ello. Pero puede que esta discusión del año 1902 (con razón dicen por ahí que Delphi está viejo ) tenga alguna relación.

Algunos usuarios de versiones anteriores a la corrección (por lo menos desde la aparición de la unidad FmtBCD hasta la 7) se han de sentir despreocupados por esto al ver que el variante es obtenido con la función VarFmtBCDCreate, pues quizá no la usan. Pero ojo avizor, porque ese mismo tipo de variante es el que devuelve un típico campo monetario Numeric que en Delphi suele representarlo un objeto de clase TFmtBCDField. La recomendación entonces creo que sería usar siempre su propiedad AsCurrency en las versiones de Delphi que presenten ese problema. Además de la 7, ¿cuál otra?

Para mi caso actual implicaría cambiar muchas referencias tipo "ConjuntoDeDatos ['Campo']" por "ConjuntoDeDatos.FieldByName ('Campo').AsCurrency", pero creo lo mejor va a ser derivar una clase interpuesta de TFmtBCDField y redefinir su método virtual GetAsVariant, de manera que éste devuelva un variante Currency en lugar de un variante BCD. Cuando suba el proyecto a Delphi 2010 o XE2 (que les tengo tantas ganas como escasez de dinero) desecharé la clase interpuesta.

Un abrazo sin-cero.

Al González.

Última edición por Al González fecha: 30-03-2012 a las 20:55:47. Razón: Poner un código más completo
Responder Con Cita
  #2  
Antiguo 30-03-2012
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.678
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Vaya, sí que es viejo delphi
No puedo ayudar mucho, ahora tengo esas mismas versiones.
Responder Con Cita
  #3  
Antiguo 30-03-2012
MartinS MartinS is offline
Miembro
NULL
 
Registrado: nov 2011
Ubicación: Villa Cacique - Argentina
Posts: 283
Poder: 15
MartinS Va por buen camino
Hola Al: Testeado en Delphi XE

Código Delphi [-]
  C3 := (C1 * V) / C2;  // ¡Resulta 5!
  ShowMessage (CurrToStr (C3));
Muestra 50

Código Delphi [-]
  C3 := (C1 * Currency (V)) / C2;  // Correcto, resulta 50
  ShowMessage (CurrToStr (C3));

muestra 50

Código Delphi [-]
  C1 := 51;
  C3 := (C1 * V) / C2;  // Resulta 51, como debe ser
  ShowMessage (CurrToStr (C3));

Muestra 51

Código Delphi [-]
 C1 := 800;
  C3 := (C1 * V) / C2;  // ¡Resulta 8!
  ShowMessage (CurrToStr (C3));

Muestra 800

Código Delphi [-]
  C1 := 802;
  C3 := (C1 * V) / C2;  // Resulta 802, como debe ser
  ShowMessage (CurrToStr (C3));
Muestra 802

Saludos
Responder Con Cita
  #4  
Antiguo 31-03-2012
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.610
Poder: 32
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Gracias Casi, gracias MartinS.

Por lo dicho anteriormente suena lógico que tras Delphi 2007 no ocurra el problema, pero si alguien tiene alguna versión entre la 7 y la 2007, exclusive, o bien anterior a Delphi 7, con la que compile ese código, sería importante conocer los resultados.

Saludos.

Al González.

P.D.
* La palabra exclusive es nueva para mí, quizá sea más correcto decir "excluyendo ambas".
* Si alguien se anima a hacer más pruebas, evite los cabezazos.
Responder Con Cita
  #5  
Antiguo 31-03-2012
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 38
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 beholdecfisa is a splendid one to behold
Hola Al.

No respondí antes por que al igual que vos tengo Delphi 7 y había entendido que sobre él hiciste las pruebas; con Delphi 7 obtuve los mismos resultados erróneos.
Lamento no tener otra versión disponible para aportarte una información más amplia.

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #6  
Antiguo 31-03-2012
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.610
Poder: 32
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
No te preocupes, ecfisa. Al menos se va perfilando que esto viene de fábrica.

Saber en qué versiones ocurre será útil para quien pueda enfrentarse al mismo problema en el futuro y encuentre este hilo.
Responder Con Cita
  #7  
Antiguo 31-03-2012
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 28
Delphius Va camino a la fama
Hola. Con D6 se obtiene:
5
50
51
8
802

Creo que esto confirma de que hay un problema con las versiones D7 e inferiores con dicha función.
Por cierto, en lo posible hay que evitar mezclar las operaciones con diferentes tipos. Aún cuando se suponga que éstos son los "más precisos".

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
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
Premium, A mi me lo quitan tambien? poliburro La Taberna 16 06-01-2009 00:00:52
Currency to float david duarte Varios 2 14-11-2006 16:53:22
Error dando formato a un TFMTBCDField HiroProtagonist Conexión con bases de datos 7 18-05-2006 00:46:04
Error de Currency Epunamun OOP 2 05-12-2005 23:41:25
Como cambiar TBcdField a TFMTBcdField Ricardo Alfredo Varios 0 31-12-2004 16:07:55


La franja horaria es GMT +2. Ahora son las 03:51:11.


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