Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   operaciones con números float. (https://www.clubdelphi.com/foros/showthread.php?t=20874)

fjardelphi 28-04-2005 09:46:23

operaciones con números float.
 
Hola.
¿Hay alguna forma de fijar en las operaciones con números float que sólo se utilicen dos decimales sin utilizar funciones de redondeo? Necesito operar con euros donde sólo se visualicen dos números decimales. Con más detalle el problema es el siguiente:

Tengo una serie de lineas de detalle donde el importe es un campo calculado:
bi:= RoundTo(DetCANTIDAD.Value*DetPVP.Value, -2)
dt:= RoundTo(DetDESCUENTO.Value / 100 ) * Basimponible,-2);
DetccImporte.Value := bi - dt;

El total lo muestro utilizando un campo Agregado cuya expresión es:
SUM(Cantidad*pvp-((descuento/100)*Cantidad*PVP))

Problema: La suma no es exacta por los decimales y el redondeo.
¿Cómo solucionais los totales de un conjunto de lineas de detalle?

Saludos y gracias.

marcoszorrilla 28-04-2005 14:22:32

Para eso yo me hice una función:
Código Delphi [-]
 function RoundEuros(Const X: Double): Double;
 var
 r:Int64;  //resto
 X2:Int64; //número
 x1:double;  //resultado
 begin
 x2:=trunc((abs(x)*1000)+0.5); //Tomo los 3 primeros decimales.
 
 r:=(x2 mod 10);//Compruebo si el 3 decimal es >=5
 x2:=trunc(x2/10);//desprecio el tercer decimal
 
   if r >= 5  then  //Si el 3 decimal era >= 5 sumo 1 al número
           x2:=x2+1;
 
   x1:=x2/100; //Construyo el número con los 2 decimales
 
   if x < 0 then
   result:=0 - x1
   else
   result:=x1;
 
 end;

Un Saludo.

Elfoscuro 28-04-2005 15:54:37

Yo lo que haría sería sumar todos los totales de línea. El problema es que no es lo mismo (10+16%) + (10+16%) que (20+16%). Se va en algunos casos de 0,1 centimos de euro, y con el redondeo a veces se ve. De todas formas, si usas tres decimales para los precios y subtotales, falla bastante.

Resumiendo, no cojas el total sin Iva y sin descuento y le apliques los porcentajes. Suma los totales parciales por linea.

Saludos del elfo

jachguate 28-04-2005 17:22:22

Cita:

Empezado por marcoszorrilla
Para eso yo me hice una función:

No seria mas simple y con el mismo resultado:

Código Delphi [-]
uses Math;
.
.
.
 function RoundEuros(Const X: Double): Double;
 begin
    Result := roundTo(x, -2);
 end;

Hasta luego.

;)

fjardelphi 28-04-2005 19:03:59

Así es como lo hago: roundto(valor, -2). Pero como trabajo con el campo agregado. Si los sumo yo no tengo problema, el problema es que en la expresión del campo agregado no es posible utilizar la función roundto.

JOSEPE 28-04-2005 19:28:06

Bueno si utilizas bases de datos (que asi parece) IB o FB puedes utilizar alguna libreria UDF que hay varias y free, o puedes usar variables Numeric o Decimal.
Estoy de acuerdo con ELfoscuro cuando sugiere en primero calcular los parciales para luego sumar el total a partir de estos.

Saludos,
JOSEPE
Lima-Peru

jachguate 28-04-2005 19:51:59

Podrias tener un campo calculado que ya haga el redondeo, y luego el agregado hacerlo sobre el campo calculado.

Hasta luego.

;)

marcoszorrilla 28-04-2005 22:04:10

Código Delphi [-]
uses Math;
 .
 .
 .
  function RoundEuros(Const X: Double): Double;
  begin
     Result := roundTo(x, -2);
  end;

El problema es que esta función no está dispnible en Delphi 5 y versiones inferiores.

Si existe en D7 y no sé en D6, yo debo reconocer que la cree para una versión de Access en que se les olvidó poner la opción redondeo y luego la adapté a Delphi 3 y hasta D5 la he venido utilizando sin ningún problema.

Un Saludo.

jachguate 28-04-2005 22:23:59

RoundTo está disponible al menos a partir de Delphi 6 en la unidad Math.

Supongo, aunque no tengo forma de probarlo, que esta unidad puede integrarse a proyectos de versiones inferiores de delphi (al menos de d4 en adelante).

Hasta luego.

;)

Lepe 29-04-2005 09:37:08

Tal como dice la ayuda de delphi 6 para RoundTo:
Cita:

Note: The behavior of RoundTo can be affected by the Set8087CW procedure or SetRoundMode function.
Por tanto, para obtener el valor correcto, tenemos que poner en algun lugar de la aplicación:

SetRoundMode(rmup);

Y ahora si:

edit6.Text:= FloatToStr(roundto(1.245,-2)); // obtines 1.25

Aunque he notado que se pueden perder millonésimas de euro. En cantidades de 3.000 € se ve un fallo de 1 centimo.

Un saludo

fjardelphi 29-04-2005 09:47:01

floats
 
Gracias por el empeño.
Pero el problema lo tengo en el campo agregado. ¿Alguién utiliza un campo agregado para calcular el total de un conjunto de lineas de detalle con descuentos? Utilizando la función RoundTo y creando una función propia que calcule el total el problema está resuelto, pero creo que es más cómodo y elegante el uso de un campo agregado (si hay alguna manera de hacerlo, claro)
Saludos.


La franja horaria es GMT +2. Ahora son las 21:13:33.

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