|
Redondeando números de diferentes maneras
Copyright © 2000 Ernesto
De Spirito
Redondeo entero
La función Round que viene con Delphi realiza lo que se llama
"redondeo bancario", significando que un número con una parte decimal
de 0.5 se redondea a veces para arriba y otras para abajo, siempre hacia
el número par más cercano. Es decir que por ejemplo Round(3.5) devuelve
4 mientras que Round(2.5) devuelve 2.
Aquí va un conjunto de funciones para redondear números,
incluyendo RoundN que redondea un número "normalmente" (es
decir que RoundN(3.5) devuelve 4 y RoundN(2.5) devuelve 3).
function Sgn(X: Extended): Integer;
// Devuelve -1, 0 o 1 de acuerdo al signo del argumento
begin
if X < 0 then
Result := -1
else if X = 0 then
Result := 0
else
Result := 1;
end;
function RoundUp(X: Extended): Extended;
// Devuelve el primer entero mayor que o
// igual al número dado en valor absoluto
// (se preserva el signo).
// RoundUp(3.3) = 4 RoundUp(-3.3) = -4
begin
Result := Int(X) + Sgn(Frac(X));
end;
function RoundDn(X: Extended): Extended;
// Devuelve el primer entero menor que o
// igual al número dado en valor absoluto
// (se preserva el signo).
// RoundDn(3.7) = 3 RoundDn(-3.7) = -3
begin
Result := Int(X);
end;
function RoundN(X: Extended): Extended;
// Redondea un numero "normalmente": si la parte decimal
// es >= 0.5 el número se redondea para arriba (ver RoundUp).
// En caso contrario, si la parte decimal es < 0.5, el
// número se redondea para abajo (ver RoundDn).
// RoundN(3.5) = 4 RoundN(-3.5) = -4
// RoundN(3.1) = 3 RoundN(-3.1) = -3
begin
(*
if Abs(Frac(X)) >= 0.5 then
Result := RoundUp(X)
else
Result := RoundDn(X);
*)
Result := Int(X) + Int(Frac(X) * 2);
end;
function Fix(X: Extended): Extended;
// Devuelve el primer entero menor
// o igual al número dado.
// Int(3.7) = 3 Int(-3.7) = -3
// Fix(3.7) = 3 Fix(-3.1) = -4
begin
if (X >= 0) or (Frac(X) = 0) then
Result := Int(X)
else
Result := Int(X) - 1;
end;
function RoundDnX(X: Extended): Extended;
// Devuelve el primer entero menor
// o igual al número dado.
// RoundDnX(3.7) = 3 RoundDnX(-3.7) = -3
// RoundDnX(3.7) = 3 RoundDnX(-3.1) = -4
begin
Result := Fix(X);
end;
function RoundUpX(X: Extended): Extended;
// Devuelve el primer entero mayor
// o igual al número dado.
// RoundUpX(3.1) = 4 RoundUpX(-3.7) = -3
begin
Result := Fix(X) + Abs(Sgn(Frac(X)))
end;
function RoundX(X: Extended): Extended;
// Redondea un numero "normalmente", pero
// tenindo en cuenta el signo.
// Si la parte decimal es >= 0.5 el número se
// redondea para arriba (ver RoundUpX).
// En caso contrario, si la parte decimal es < 0.5,
// el número se redondea para abajo (ver RoundDnX).
// RoundX(3.5) = 4 RoundX(-3.5) = -3
begin
(*
if Abs(Frac(X)) >= 0.5 then
Result := RoundUpX(X)
else
Result := RoundDnX(X);
*)
Result := Fix(X + 0.5);
end;
Redondeo a una cifra decimal
Estas funciones que acabamos de presentar siempre redondean el último
dígito entero, pero a veces necesitamos redondear por ejemplo la segunda
cifra decimal o los miles, millones y billones. La siguiente función
realiza un "redondeo normal" tomando un parámetro adicional para indicar
el dígito a ser redondeado:
function RoundD(x: Extended; d: Integer): Extended;
// RoundD(123.456, 0) = 123.00
// RoundD(123.456, 2) = 123.46
// RoundD(123456, -3) = 123000
var
n: Extended;
begin
n := IntPower(10, d);
x := x * n;
Result := (Int(x) + Int(Frac(x) * 2)) / n;
end;
|