É muito comum encontrar programadores Delphi que têm dúvidas sobre como arredondar um valor real para "n" casas após o separador decimal. A princípio parece um problema simples, pois o próprio Delphi já possui uma função que arredonda para o inteiro mais próximo, a qual poderia facilmente ser utilizada para arredondar para qualquer quantidade de casas decimais. Exemplo:
{ x receberá o valor de y arredondado para 2 casas após o separador. }
x := Round(y * 100) / 100;
{ z receberá o valor de y arredondado para 3 casas após o separador. }
z := Round(y * 1000) / 1000;
No entanto dois problemas poderão aparecer com os exemplos acima:
- O arredondamento feito pelo Delphi difere daquele feito pelas calculadores financeiras, bem como bancos de dados como InterBase e FireBird.
- poderão ocorrer pequenos arredondamentos devido ao modo como o Delphi trata números reais, tais como aparecer 3.9999999... em vez de 4.
A função abaixo resolve estes dois problemas.
{ Esta função faz arredondamento de valores reais para "n" casas
decimais após o separador decimal, seguindo os critérios das
calculadoras financeiras e dos bancos de dados InterBase e FireBird.
}
function TBRound(Value: Extended; Decimals: integer): Extended;
var
Factor, Fraction: Extended;
begin
Factor := IntPower(10, Decimals);
{ A conversão para string e depois para float evita
erros de arredondamentos indesejáveis. }
Value := StrToFloat(FloatToStr(Value * Factor));
Result := Int(Value);
Fraction := Frac(Value);
if Fraction >= 0.5 then
Result := Result + 1
else if Fraction <= -0.5 then
Result := Result - 1;
Result := Result / Factor;
end;
Criei a seguinte formatação, mais simples e segura.
ResponderExcluir----------------------------------------------
function FormataDecimal(Valor:Extended;Casas:Integer): String;
var i:integer;
mask1,mask2,S: string;
begin
mask1:='#,';
mask2:='0.';
for i:=1 to Casas do
begin
mask1:=mask1+'#';
mask2:=mask2+'0';
end;
Result:=FormatFloat(mask1+mask2,Valor);
end;