/ / Ao converter NaN em int, por que o valor muda dependendo se é atribuído a uma variável ou não? - c #

Quando converter NaN em int, por que o valor muda dependendo se ele é atribuído a uma variável ou não? - c #

Casting double.NaN para int será 0.

Console.WriteLine(unchecked((int)double.NaN));    // 0

No entanto, atribuir double.NaN a uma variável e, em seguida, converter para int será -2147483648.

double value = double.NaN;
Console.WriteLine (unchecked ((int) value));    // -2147483648
Console.WriteLine ((int) value);                // -2147483648

Por que o resultado muda dependendo se é ou não atribuído a uma variável?

Especificação C #

6.2.1 Conversões numéricas explícitas

  • Em um contexto verificado, a conversão procede da seguinte forma:
    • Se o valor do operando for NaN ou infinito, uma System.OverflowException é lançada.
    • Caso contrário, o operando de origem é arredondado para zero para o valor integral mais próximo. Se esse valor integral estiver dentro do intervalo do tipo de destino, esse valor é o resultado da conversão.
    • Caso contrário, uma System.OverflowException é lançada.
  • Em um contexto não verificado, a conversão sempre é bem-sucedida e prossegue da seguinte maneira.
    • Se o valor do operando for NaN ou infinito, o resultado da conversão é um valor não especificado do tipo de destino.
    • Caso contrário, o operando de origem é arredondado para zero para o valor integral mais próximo. Se esse valor integral estiver dentro do intervalo do tipo de destino, esse valor é o resultado da conversão.
    • Caso contrário, o resultado da conversão é um valor não especificado do tipo de destino.

Envrionment

  • Compilador: Visual Studio 2013
  • Rimtime: .NET Framework 4.6.0
  • SO: Windows 10 Versão 1607
  • CPU: Intel Core i7 920

Janelas:

Console.WriteLine(Environment.OSVersion);    // Microsoft Windows NT 6.2.9200.0
Console.WriteLine(Environment.Version);      // 4.0.30319.42000

Respostas:

3 para resposta № 1

Por padrão, um aplicativo de console é compilado como unchecked. É por isso que seu último exemplo mostra o mesmo valor que os exemplos usando explicitamente unchecked.

Para o restante de seus exemplos, a seção de especificações que você citou se aplica:

  • Em um contexto não verificado, a conversão sempre é bem-sucedida e prossegue da seguinte maneira.
    • Se o valor do operando for NaN ou infinito, o resultado da conversão será um valor não especificado do tipo de destino.

(enfatizando por mim).

Não especificado significa que você não pode confiar no resultado. Pode ser 0 ou -2147483648 ou qualquer outra coisa.

Eu gostaria de descobrir o que acontece sob o capô em seu caso especial, mas eu entendo -2147483648 para ambas as maneiras. Portanto, é difícil rastrear.


1 para resposta № 2

Depois de olhar em volta, acho que entendi o que está acontecendo aqui. Você não está escalando 0, você está escalando NaN. intou Int32 tem um alcance muito menor do que double. Eu pensar essas regras deliciosamente nada claras estão trabalhando juntas para fazer a diferença:

  • Se o valor do operando for NaN ou infinito,o resultado da conversão é um valor não especificado do tipo de destino. Caso contrário, o operando de origem é arredondado para zero para o valor integral mais próximo.
  • Se esse valor integral estiver dentro do intervalo do tipo de destino, esse valor é o resultado da conversão.

O tipo de destino aqui é o menor int, e o valor "-2147483648" que você está recebendo é o valor mínimo de um inteiro assinado de 32 bits. Isso sugere que a operação de conversão está convertendo o NaN em double.NegativeInfinity para realizar uma operação com ele. O inteiro mais próximo de double.NegativeInfinity é int.MinValue, que é o valor que você está obtendo.

Dito isso, o fato de que esse valor é não especificado significa que o resultado obtido também pode dependermuitos fatores, até mesmo se você atribuiu ou não uma variável ou mesmo qual arquitetura de processador você possui. Você não deve usar a conversão NaN para fazer algo significativo, então NaN nunca é atribuído um valor definido real (principalmente porque seria, por definição, um número). Para a maioria dos propósitos, um resultado NaN deve ser tratado como um erro por esse motivo. O valor real é, no final, sem sentido.