Em nosso código, temos um duplo que precisamos converter em um int.
double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;
Alguém pode me explicar por quê i1 != i2
?
O resultado que obtenho é: i1 = 9
e i2 = 8
.
Em nosso código, temos um duplo que precisamos converter em um int.
double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;
Alguém pode me explicar por quê i1 != i2
?
O resultado que obtenho é: i1 = 9
e i2 = 8
.
Respostas:
Porque Convert.ToInt32
rondas:
Valor de retorno: arredondado para o inteiro assinado de 32 bits mais próximo. Se o valor estiver na metade do caminho entre dois números inteiros, o número par será retornado; ou seja, 4,5 é convertido em 4 e 5,5 é convertido em 6.
... enquanto o elenco trunca :
Quando você converte de um valor duplo ou flutuante em um tipo integral, o valor é truncado.
Atualização: Veja o comentário de Jeppe Stig Nielsen abaixo para diferenças adicionais (que, entretanto, não entram em jogo se score
for um número real como é o caso aqui).
score
fosse 8.5
em vez de 8.6
. Eu atualizei a resposta para incluir as aspas. Obrigado pela contribuição.
score
for NaN
ou infinito ou finito, mas fora do intervalo de Int32
, Convert.ToInt32
lançará uma exceção. O elenco retornará um int
, mas você não saberá qual (na minha implementação é Int32.MinValue
) porque você está emunchecked
contexto. (Se você estiver no checked
contexto, o elenco também lançará uma exceção nesses casos.)
Double
número tipo 10000000000.6
(dez bilhões vírgula seis) é um número "real". Usar um elenco para int
isso dará um resultado estranho (a menos que você esteja no checked
contexto, mas provavelmente não está).
A conversão irá ignorar qualquer coisa após a vírgula decimal, então 8,6 se torna 8.
Convert.ToInt32(8.6)
é a maneira segura de garantir que seu duplo seja arredondado para o número inteiro mais próximo, neste caso, 9.
No exemplo fornecido, seu decimal é 8,6 . Se fosse 8,5 ou 9,5, a afirmação i1 == i2 poderia ser verdadeira. De fato, seria verdadeiro para 8,5 e falso para 9,5.
Explicação:
Independentemente da parte decimal, a segunda declaração, int i2 = (int)score
descartará a parte decimal e simplesmente retornará a parte inteira. Uma coisa muito perigosa de se fazer, pois pode ocorrer perda de dados.
Agora, para a primeira declaração, duas coisas podem acontecer. Se a parte decimal for 5, ou seja, está no meio, uma decisão deve ser tomada. Nós arredondamos para cima ou para baixo? Em C #, a classe Convert implementa o arredondamento do banqueiro. Veja isso resposta para uma explicação mais detalhada. Simplificando, se o número for par, arredonde para baixo; se o número for ímpar, arredonde para cima.
Por exemplo, considere:
double score = 8.5;
int i1 = Convert.ToInt32(score); // 8
int i2 = (int)score; // 8
score += 1;
i1 = Convert.ToInt32(score); // 10
i2 = (int)score; // 9
ToInt32 rounds. Casting para int apenas descarta o componente não inteiro.
Math.Truncate(score)
é intenção expressa mais explicitamente do que(int)score