Pergunta

Não estou vendo o resultado que eu esperar com Math.Round.

return Math.Round(99.96535789, 2, MidpointRounding.ToEven); // returning 99.97

Como eu entendo MidpointRounding.ToEven, a 5 na posição milésimos deve causar a saída seja 99,96. Não é este o caso?

Eu até tentei isso, mas voltou 99,97, bem como:

return Math.Round(99.96535789 * 100, MidpointRounding.ToEven)/100;

O que estou ausente

Obrigado!

Foi útil?

Solução

Você não é realmente no ponto médio. MidpointRounding.ToEven indica que se você tivesse o número 99,965 , ou seja, 99,96500000 [etc.], então você obteria 99,96. Como o número que você está passando para Math.Round está acima deste ponto médio, é o arredondamento para cima.

Se você quiser que o seu número para baixo e volta para 99,96, faça o seguinte:

// this will round 99.965 down to 99.96
return Math.Round(Math.Truncate(99.96535789*1000)/1000, 2, MidpointRounding.ToEven);

E hey, aqui está uma função pouco útil para fazer o descrito acima para casos gerais:

// This is meant to be cute;
// I take no responsibility for floating-point errors.
double TruncateThenRound(double value, int digits, MidpointRounding mode) {
    double multiplier = Math.Pow(10.0, digits + 1);
    double truncated = Math.Truncate(value * multiplier) / multiplier;
    return Math.Round(truncated, digits, mode);
}

Outras dicas

É apenas rodadas para 99,96 se você estiver no próprio ponto médio, ou seja, 99,965:

C:\temp>ipy
IronPython 2.6 Beta 2 (2.6.0.20) on .NET 2.0.50727.4927
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> from System import Math, MidpointRounding
>>> Math.Round(99.9651, 2, MidpointRounding.ToEven)
99.97
>>> Math.Round(99.965, 2, MidpointRounding.ToEven)
99.96
>>> Math.Round(99.9649, 2, MidpointRounding.ToEven)
99.96
>>> Math.Round(99.975, 2, MidpointRounding.ToEven)
99.98
>>>

O valor MidpointRounding só entra em jogo quando você está tentando para arredondar um valor cujo dígito menos significativo é exatamente 5. Em outras palavras, o valor teria que ser 99.965 para obter o resultado desejado . Uma vez que este não é o caso aqui, você está simplesmente observando o mecanismo de arredondamento padrão. Veja a MSDN página para mais informações.

Eis os resultados que lançar alguma luz sobre o assunto:

Math.Round(99.96535789, 2, MidpointRounding.ToEven); // returning 99.97
Math.Round(99.965, 2, MidpointRounding.ToEven);      // returning 99.96
Math.Round(99.96500000, 2, MidpointRounding.ToEven); // returning 99.96

O ponto médio é exatamente 5 ... não 535789, não 499.999.

O arredondamento ponto médio é olhado somente se o valor estiver entre seus dois casos.

No seu caso, não é "5", que é "535 ...", por isso é maior do que o ponto médio, e rotinas para 0,96. Para obter o comportamento o seu esperando, você precisaria trunctate ao terceiro ponto decimal, em seguida, volta usando MidpointRounding.ToEven.

'Arredonda um valor decimal para um número especificado de dígitos fracionários.' Math.round quando arredondamento 99.96500000,2 rodadas para 99,96 e 99,96500001-99,67. Ele arredonda o valor completo.

Se fosse comigo, eu não iria usar Math.Round(), porque isso não é o que você está tentando realizar.

Isto é o que eu faria:

double num = 99.96535789;
double percentage = Math.Floor(100 * num) / 100;  

O que é muito mais fácil de ler e é mais uma abordagem matemática.
I multiplicar o número por 100, agora eu tenho 9996.535789.
Então chão, o que é distintamente diferente do que o arredondamento, para retornar o menor número inteiro mais próximo ao número, para obter 9996.
Eu, então, dividir por 100 para obter o 99.96 necessário.

P.S.
Piso é o oposto de teto , que retorna o maior inteiro mais próximo do número.
Assim, o teto de 9996.535789 é 9997.
Ambos são diferentes do arredondamento para sem pontos decimais, o que realmente retorna o inteiro mais próximo ao número, seja ele menor ou maior - o que for mais próximo; é por isso que você estava recebendo 99.97 quando você usou arredondamento .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top