De acordo com a documentação, o decimal.Round
método usa um algoritmo de arredondamento para o mesmo que não é comum na maioria dos aplicativos. Por isso, sempre acabo escrevendo uma função personalizada para executar o algoritmo round-half-up mais natural:
public static decimal RoundHalfUp(this decimal d, int decimals)
{
if (decimals < 0)
{
throw new ArgumentException("The decimals must be non-negative",
"decimals");
}
decimal multiplier = (decimal)Math.Pow(10, decimals);
decimal number = d * multiplier;
if (decimal.Truncate(number) < number)
{
number += 0.5m;
}
return decimal.Round(number) / multiplier;
}
Alguém sabe o motivo por trás dessa decisão de design da estrutura?
Existe alguma implementação interna do algoritmo round-half-up na estrutura? Ou talvez alguma API do Windows não gerenciada?
Pode ser enganoso para iniciantes que simplesmente escrevem decimal.Round(2.5m, 0)
esperando 3 como resultado, mas obtendo 2.
Respostas:
Provavelmente porque é um algoritmo melhor. No decorrer de muitos arredondamentos realizados, você calculará a média de que todos os 0,5 terminam arredondando igualmente para cima e para baixo. Isso fornece melhores estimativas dos resultados reais, se você estiver, por exemplo, adicionando vários números arredondados. Eu diria que, embora não seja o que alguns possam esperar, é provavelmente a coisa mais correta a se fazer.
fonte
As outras respostas, com razões pelas quais o algoritmo do Banker (também conhecido como metade da rodada até o par ) é uma boa opção, estão bem corretas. Ele não sofre viés negativo ou positivo, tanto quanto a metade da metade do método zero , sobre a maioria das distribuições razoáveis.
Mas a pergunta era por que o .NET usa o arredondamento real do Banker como padrão - e a resposta é que a Microsoft seguiu o padrão IEEE 754 . Isso também é mencionado no MSDN for Math.Round em Comentários.
Observe também que o .NET suporta o método alternativo especificado pelo IEEE, fornecendo a
MidpointRounding
enumeração. É claro que eles poderiam ter fornecido mais alternativas para resolver laços, mas optam apenas por cumprir o padrão IEEE.fonte
Embora eu não possa responder à pergunta "Por que os designers da Microsoft escolheram isso como padrão?", Só quero salientar que uma função extra é desnecessária.
Math.Round
permite que você especifique umMidpointRounding
:fonte
Os decimais são usados principalmente para dinheiro ; O arredondamento do banqueiro é comum quando se trabalha com dinheiro . Ou você poderia dizer.
Os arredondamentos dos banqueiros têm a vantagem de que, em média, você obterá o mesmo resultado se:
O arredondamento antes da adição economizava muito trabalho nos dias anteriores aos computadores.
(No Reino Unido, quando entramos em bancos decimais, não lidamos com meia moeda, mas por muitos anos ainda havia uma moeda de meia moeda e a loja geralmente tinha preços que terminavam em meia moeda - muito arredondamento)
fonte
Decmial
s sim Decimais, não. Para a posteridade, concordo com o sentimento original aqui.Use outra sobrecarga da função Round como esta:
Ele produzirá 3 . E se você usar
você receberá o arredondamento dos banqueiros.
fonte