Fórum arredondamento - não consigo chegar a 100¬ #336496
19/01/2007
0
item1 R$ 100,00 12,5¬
item2 R$ 250,00 31,25¬
item3 R$ 450,00 56,25¬
total R$ 800,00
apresento qto representa cada valor em ¬ sobre o valor total...
a minha lista tem mais de 60 itens, com valores diversos....
testei 3 formas de arredondamento e em nenhum deles consegui totalizar 100¬
rotinas utilizadas:
1)
function TForm1.Arredondar(value: double; casas: integer): double;
Var fracao:real;
decimal:string;
begin
try
fracao:=Frac(value); //Retorna a parte fracionária de um número
decimal:=(RightStr(floattostr(fracao),length(floattostr(fracao))-2)); //decimal recebe a parte decimal
//enquanto o tamanho da variavel decimal for maior que o número de casas faça
while length(decimal) > casas do
begin
//Verifica se o último digito da variável decimal é maior que 5
if strtoint(RightStr(decimal,1))>5 then
begin
//Descarta o último digito da variável Decimal
decimal:=leftstr(decimal,length(decimal)-1);
//Soma o valor número da variavel decimal + 1
decimal:=floattostr(strtofloat(decimal) + 1);
end
else
decimal:=leftstr(decimal,length(decimal)-1); //Descarta o último digito da variável Decimal
end;
result:=(int(value) + (strtofloat(decimal)/100)); //devolve o resultado para a função
except
Raise Exception.Create(´Erro no arredondamento´);
end;
end;
2)
RoundNExtend(valor,2);
3)
function TForm1.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;
em todas uso duas casas decimais....
o mais proximo que chego é 99,94¬
alguem tem alguma sugestão ???? ja fiz algumas pesquisas no forum tbem, mas não consegui solucionar este problema....
Arc
Curtir tópico
+ 0Posts
19/01/2007
Emerson Nascimento
de posse desse valor, faça algo assim:
// duas casas decimais
usando RoundTo():
percentual := RoundTo( (valoritem / valortotal) * 100, -2 );
calculo direto:
percentual := Round( (valoritem / valortotal) * 10000 ) / 100;
ou
// três casas decimais
usando RoundTo():
percentual := RoundTo( (valoritem / valortotal) * 100, -3 );
calculo direto:
percentual := Round( (valoritem / valortotal) * 100000 ) / 1000;
(a função RoundTo() está na unit Math)
quanto maior o número de casas decimais, mais o valor será aproximado.
Gostei + 0
19/01/2007
Arc
RoundNExtend é o nome de uma outra função que tbem testei anteriormente.
se eu usar o RoundTo com duas casas decimais, ele não totaliza 100¬
com 3 casas sim, o problema esta na hora de exibir os valores, pois uso a mascara #,0.00¬ para exibi-los com duas casas, ..., se vc somar a coluna, vai chegar no mesmo valor se fizesse o arredondamento com duas casas.
Gostei + 0
19/01/2007
Eng_diehl
Veja bem, quando voce arredonda um valor segundo convenções matemáticas acontece o seguinte:
5,77 = 5,8
5,44 = 5,4
4,46 = 4,5
3,55 = 3,6
Isto significa que a probabilidade da soma dos seus valores arredondados ser igual a dos valores originais é extremamente remota.
Sugiro que voce faça uma rotina que escolha o menor valor de todos os dados que formam o seu 100¬. Para o calculo da porcentagem exclua este valor some o restante. Calcule a porcentagem deste somatorio e diminua de 100¬. Voce terá uma aproximação muito boa, já que matematicamente nunca conseguirá um resultado melhor que este com arredondamentos.
Qualquer coisa estou ai...
Abraçoo
Gostei + 0
19/01/2007
Eng_diehl
Dai fecha tb....
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)