Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Función para redondear números reales (https://www.clubdelphi.com/foros/showthread.php?t=25972)

Dexter182 10-10-2005 03:26:04

Función para redondear números reales
 
Les escribo para saber si alguien conoce alguna función para redondear
números reales que funcione de la siguiente manera:

$ 1,241 = $ 1,25
$ 1,239 = $ 1,25
$ 1,210 = $ 1,20

La idea es que indique valores reales de dinero.
He logrado algo parecido con la función RoundTo(Valor,-2),
pero no es lo mismo (No es válido cobrar $1,24 o $1,23).

Bueno, espero que se entienda.
Un saludo.

Sotrono 10-10-2005 04:16:24

Podes utilizar la funcion Frac (que toma la parte decimal de un numero) y desarrollar una funcion vos.

Saludos..

Sotrono 10-10-2005 05:31:11

Hola, la explicacion anterior fue bastante pobre... :(
Hice esta funcion que por los resultados que me dio parece funcionar:

Código Delphi [-]
function TForm1.RedondearPesos(var Numero: Real): Real;

function Redondear(Valor: Real; Redondeo: Integer):Real;
//Esta funcion (Redondear) fue sacada de Trucomania
begin
  Redondear := Round(Valor * Power(10, Redondeo)) / Power(10,Redondeo);
end;

var
  num: string;
  i: integer;
begin
  numero:= Redondear(numero, 2);
  if Frac(numero) > 0.95 then
    numero:= Redondear(numero,0);
  num:= FloatToStr(numero);
  for i:= Length(num) downto (Pos(',', num) + 2) do
    if (num[i] = '4') or (num[i] = '6') then
      num[i]:= '5'
    else if (num[i] = '1') or (num[i]= '2') then
      num[i]:= '0'
    else if (num[i] = '8') or (num[i] = '9') then
     begin
      numero:= Redondear(numero, 1);
      num:= FloatToStr(numero);
     end;
  Result:= StrToFloat(num);
end;
Le tendrias que hacer algunos retoques. No se que resultado queres cuando el numero es, por ejemplo 2,43 o 2,47.

Espero que te sirva..

Bytes...

Torreblanca 10-10-2005 06:43:28

Hola yo tambien estaba en esas hasta que encontre esta función

FloatToStrF()

la siguiente pagina explica su funcionamiento un poco mejor que en la ayuda de Delphi

http://www.delphibasics.co.uk/RTL.asp?Name=FloatToStrF

yo lo use de la sig manera:

FloatToStrF(sueldo,ffCurrency,8,2);

lo que hace es que con la variable "sueldo" que es Double la formateas como moneda, el 8 es la precision y el 2 son los decimales que deseas y te manda la variable con todo y signo de pesos. Ademas trae otros formatos como:
ffCurrency ffExponent ffFixed ffGeneral ffNumber

Espero te sirva.

Delfino 10-10-2005 08:57:02

Tambien esta la funcion FormatFloat..

jachguate 10-10-2005 16:54:03

Podriamos inventar una función que, dado un valor, haga un redondeo al múltiplo mas cercano (por ejemplo del valor mínimo de la moneda de tu pais, que parece ser de 5 centimos).

así:

Código Delphi [-]
type
  TTipoRedondeo = (trMatematico, trAlMenor, trAlMayor);

function jachRedondeaMultiplos(valor, base : extended;
  TipoRedondeo : TTipoRedondeo = trMatematico; DigitosPrecision : Integer = 2) : extended;
var
  multiplicando : Int64;
  fraccion : Extended;
const
  precision_fraccion = 6;
begin
  multiplicando := round(valor / base);
  fraccion := roundTo(frac(valor / base), -precision_fraccion);
  case TipoRedondeo of
    trAlMayor : if (fraccion > 0) and
                   (fraccion < 0.5) then
                  multiplicando := multiplicando + 1;
    trAlMenor : if (fraccion >= 0.5) and
                   (fraccion < 1) then
                  multiplicando := multiplicando - 1;
  end;
  result := roundTo(multiplicando * base, -DigitosPrecision);
end;

Los parámetros son:

Valor: el valor que queres redondear,
base: la moneda de menor denominación de tu pais (o a la que te interese redondear)
TipoRedondeo: creo que no necesita explicación.. ;)
DigitosPrecision: Cuantos dígitos de precisión se usan en la moneda de tu pais. Si son céntimos, el valor será 2 (el que tiene por defecto).

Una llamada típica entonces podria ser:

Código Delphi [-]
  jachRedondeaMultiplos(Producto.costo * factorganancia, 0.05, trAlMayor);

Te aclarará también la siguiente tabla de resultados de llamadas a la función (asumiendo un redondeo a monedas de 0.05

Código:

|-----------|-----------|-----------|-----------|
|  valor  | matemático|  al menor |  al mayor |
|-----------|-----------|-----------|-----------|
|    1.41  |    1.40  |    1.40  |    1.45  |
|    1.45  |    1.45  |    1.45  |    1.45  |
|    7.23  |    7.25  |    7.20  |    7.25  |
|  14.32  |    14.30  |    14.30  |    14.35  |
|    8.69  |    8.70  |    8.65  |    8.70  |
|-----------|-----------|-----------|-----------|

Hasta luego.

;)

Dexter182 13-10-2005 03:58:33

Perdón por la demora
 
Cita:

Empezado por Sotrono
Hola, la explicacion anterior fue bastante pobre... :(
Hice esta funcion que por los resultados que me dio parece funcionar:

Código Delphi [-]
function TForm1.RedondearPesos(var Numero: Real): Real;
 
function Redondear(Valor: Real; Redondeo: Integer):Real;
//Esta funcion (Redondear) fue sacada de Trucomania
begin
Redondear := Round(Valor * Power(10, Redondeo)) / Power(10,Redondeo);
end;
 
var
num: string;
i: integer;
begin
numero:= Redondear(numero, 2);
if Frac(numero) > 0.95 then
numero:= Redondear(numero,0);
num:= FloatToStr(numero);
for i:= Length(num) downto (Pos(',', num) + 2) do
if (num[i] = '4') or (num[i] = '6') then
num[i]:= '5'
else if (num[i] = '1') or (num[i]= '2') then
num[i]:= '0'
else if (num[i] = '8') or (num[i] = '9') then
begin
numero:= Redondear(numero, 1);
num:= FloatToStr(numero);
end;
Result:= StrToFloat(num);
end;
Le tendrias que hacer algunos retoques. No se que resultado queres cuando el numero es, por ejemplo 2,43 o 2,47.

Espero que te sirva..

Bytes...

Hola, acá estoy de nuevo.
Uy, la cantidad de mensajes que me perdí.
Antes que nada, debo agradecer la función que me
pasó Sotrono.
La verdad me vino de maravillas.
Le hice algunas modificaciones.
La función Redondear la saqué y usé RoundTo, ya que hace lo mismo.
Y después le arreglé un pequeño error, que se producía cuando
el número a redondear no tenía decimales.
Lo solucioné preguntando si Pos(',', num) era distinto de cero.
Aparentemente ahora funciona 10 puntos.

Ahí va el código:

Código:

function TForm1.RedondearPesos(var Numero: Real): Real;
var
  num: string;
  i: integer;
begin
  numero:= RoundTo(numero, -2);
  num:= FloatToStr(numero);
  if (Pos(',', num)) <> 0 then
        for i:= Length(num) downto (Pos(',', num) + 2) do
          if (num[i] = '3') or (num[i] = '4') or (num[i] = '6') then
                num[i]:= '5'
          else if (num[i] = '1') or (num[i]= '2') then
                num[i]:= '0'
          else if (num[i]='7') or (num[i] = '8') or (num[i] = '9') then
                begin
                  numero:= RoundTo(numero, -1);
                  num:= FloatToStr(numero);
                end;
  Result:= StrToFloat(num);
end;

Bueno, debo agradecer la ayuda de todos y bueno,
ahora voy a probar todas las otras posibilidades.
Igualmente, el problema ya está solucionado.
Pero nunca viene de más aprender un poco. :)
Agradezco de nuevo la ayuda de todos.
Un saludo.


La franja horaria es GMT +2. Ahora son las 16:17:21.

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