Redondear numeros reales

Aquí tienen varias formas de redondear correctamente números reales:



Opcion1:

======



function RoundStr(Zn: Real; kol_zn: Integer): Real;

var

snl, s, s0, s1, s2: string;

n, n1: Real;

nn, i: Integer;

begin

s := FloatToStr(Zn);

if (Pos(',', s) > 0) and (Zn > 0) and

(Length(Copy(s, Pos(',', s) + 1, length(s))) > kol_zn) then

begin

s0 := Copy(s, 1, Pos(',', s) + kol_zn - 1);

s1 := Copy(s, 1, Pos(',', s) + kol_zn + 2);

s2 := Copy(s1, Pos(',', s1) + kol_zn, Length(s1));

n := StrToInt(s2) / 100;

nn := Round(n);

if nn >= 10 then

begin

snl := '0,';

for i := 1 to kol_zn - 1 do

snl := snl + '0';

snl := snl + '1';

n1 := StrToFloat(Copy(s, 1, Pos(',', s) + kol_zn)) + StrToFloat(snl);

s := FloatToStr(n1);

if Pos(',', s) > 0 then

s1 := Copy(s, 1, Pos(',', s) + kol_zn);

end

else

s1 := s0 + IntToStr(nn);

if s1[Length(s1)] = ',' then

s1 := s1 + '0';

Result := StrToFloat(s1);

end

else

Result := Zn;

end;



Opcion 2:



function RoundEx(X: Double; Precision: Integer ): Double;



// Precision : 1, 10,100 ...



var

ScaledFractPart, Temp: Double;

begin

ScaledFractPart := Frac(X) * Precision;

Temp := Frac(ScaledFractPart);

ScaledFractPart := Int(ScaledFractPart);

if Temp >= 0.5 then

ScaledFractPart := ScaledFractPart + 1;

if Temp <= -0.5 then

ScaledFractPart := ScaledFractPart - 1;

Result := Int(X) + ScaledFractPart / Precision;

end;



Opcion 3:



function FormatData(s: String; i: Integer): String;

begin

Result:=FloatToStr(Round(StrToFloat(s)*exp(i*ln(10)))/(exp(i*ln(10))));

end;



Opcion 4:



function RoundFloat(R: Extended; Decimals: Integer): Extended;

var

Factor: Extended;

begin

Factor := Int(Exp(Decimals * Ln(10)));

Result := Round(Factor * R) / Factor;

end;




La llamada sería de la siguiente forma:



showmessage(FloatToStr(RoundStr(2.3456789,3)));

showmessage(FloatToStr(RoundEx(2.3456789,1000)));

showmessage(formatdata('2,3456789',3));

showmessage(FloatToStr(RoundFloat(2.3456789,3)));




Al trabajar con imágenes en 3D he tenido que utilizar alguna de estas funciones y lo que he hecho para acelerar su cálculo es aumentar la prioridad de mi aplicación con la siguiente función:



procedure TForm1.AumentaPrioridad;

var

ProcessID : DWORD;

ProcessHandle : THandle;

ThreadHandle : THandle;

begin

ProcessID := GetCurrentProcessID;

ProcessHandle := OpenProcess(PROCESS_SET_INFORMATION,

false, ProcessID);

SetPriorityClass(ProcessHandle, REALTIME_PRIORITY_CLASS);

ThreadHandle := GetCurrentThread;

SetThreadPriority(ThreadHandle, THREAD_PRIORITY_TIME_CRITICAL);

end;








No hay comentarios:

Publicar un comentario

Simulación del movimiento de los electrones en un campo electrico

Espectacular simulación realizada con OpenGL del movimiento de los electrones cuando atraviesan un campo eléctrico. Como muestra la image...