Arredondamento de valores Formato ABNT

Regras de arredondamento na Numeração Decimal - Norma ABNT NBR 5891 Dezembro de 1977.
Mais informações:
  • O algarismo a ser conservado no sistema ISS.Net é o segundo após a vírgula.
  • Serão considerados as 6 casas após a vírgula para os cálculos.
2. Regras
2.1 Quando o algarismo a ser conservado for seguido de algarismo inferior a 5, permanece o algarismo a ser conservado e retiram-se os posteriores.
Ex.: 86,06 * 5% = 4,303 fica 4,30, visto que o 3 é inferior a 5.
2.2 Quando o algarismo a ser conservado for seguido de algarismo superior a 5, ou igual a 5 seguido de no mínimo um algarismo diferente de zero, soma-se uma unidade ao algarismo a ser conservado e retiram-se os posteriores.
Ex.1: 309,75 * 5% = 15,4875 fica 15,49, visto que o 7 é superior a 5.
Ex.2: 602,27* 2% = 12,0454 fica 12,05, visto que os algarismos seguintes ao 5 são diferentes de zero.
2.3 Quando o algarismo a ser conservado for ímpar, seguido de 5 e posteriormente de zeros, soma-se uma unidade ao algarismo a ser conservado e retiram-se os posteriores.
Ex.: 515,50 * 5% = 25,7750 fica 25,78, visto que 7 é ímpar e é seguido por 5 e zeros.
2.4 Quando o algarismo a ser conservado for par, seguido de 5 e posteriormente de zeros, permanece o algarismo a ser conservado e retiram-se os posteriores.
Ex.: 750,00 * 4,23% = 31,72500 fica 31,72, pois 2 é par, seguido por 5 e depois por zeros.
Para desenvolver isso em Delphi encontrei a solução dentro do ACBR veja a solução abaixo.:

function RoundABNT(const AValue: Double; const Digits: TRoundToRange;
  const Delta: Double): Double;
var
   Pow, FracValue, PowValue : Extended;
   RestPart: Double;
   IntCalc, FracCalc, LastNumber, IntValue : Int64;
   Negativo: Boolean;
Begin
   Negativo  := (AValue < 0);

   Pow       := intpower(10, abs(Digits) );
   PowValue  := abs(AValue) / 10 ;
   IntValue  := trunc(PowValue);
   FracValue := frac(PowValue);

   PowValue := SimpleRoundToEX( FracValue * 10 * Pow, -9) ; // SimpleRoundTo elimina dizimas ;
   IntCalc  := trunc( PowValue );
   FracCalc := trunc( frac( PowValue ) * 100 );

   if (FracCalc > 50) then
     Inc( IntCalc )

   else if (FracCalc = 50) then
   begin
     LastNumber := round( frac( IntCalc / 10) * 10);

     if odd(LastNumber) then
       Inc( IntCalc )
     else
     begin
       RestPart := frac( PowValue * 10 ) ;

       if RestPart > Delta then
         Inc( IntCalc );
     end ;
   end ;

   Result := ((IntValue*10) + (IntCalc / Pow));
   if Negativo then
     Result := -Result;
end;

Quem utiliza o ACBR irá encontrara essa função dentro do ACBrUtil

Comentários

Postagens mais visitadas deste blog

Como fazer leitura de Arquivo CSV e XLS em Delphi

Serializar e desserializar JSON em Delphi de Forma nativa