简体   繁体   中英

When cast NaN to int, why does the value change depending on whether it is assigned to a variable or not?

Casting double.NaN to int will be 0.

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

However, assigning double.NaN to a variable and then casting to int will be -2147483648.

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

Why does the result change depending on whether or not assign it to a variable?

C# Specification

6.2.1 Explicit numeric conversions

  • In a checked context, the conversion proceeds as follows:
    • If the value of the operand is NaN or infinite, a System.OverflowException is thrown.
    • Otherwise, the source operand is rounded towards zero to the nearest integral value. If this integral value is within the range of the destination type then this value is the result of the conversion.
    • Otherwise, a System.OverflowException is thrown.
  • In an unchecked context, the conversion always succeeds, and proceeds as follows.
    • If the value of the operand is NaN or infinite, the result of the conversion is an unspecified value of the destination type.
    • Otherwise, the source operand is rounded towards zero to the nearest integral value. If this integral value is within the range of the destination type then this value is the result of the conversion.
    • Otherwise, the result of the conversion is an unspecified value of the destination type.

Envrionment

  • Compiler: Visual Studio 2013
  • Rimtime: .NET Framework 4.6.0
  • OS: Windows 10 Version 1607
  • CPU: Intel Core i7 920

Windows:

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

By default a console app is compiled as unchecked . Thatswhy your last example shows the same value as the examples explicitly using unchecked .

For the rest of your examples, the specification section you quoted applies:

  • In an unchecked context, the conversion always succeeds, and proceeds as follows.
    • If the value of the operand is NaN or infinite, the result of the conversion is an unspecified value of the destination type.

(emphasizing by me).

Unspecified means that you cannot rely on the result. It can be 0 or -2147483648 or anything else.

I'd like to figure out what happens under the hood in your special case, but I get -2147483648 for both ways. So it's hard to track down.

After looking around a bit, I think I get what's happening here. You're not casting 0, you're casting NaN. int , or Int32 has a much smaller range than double . I think these delightfully not-so-clear rules are working together to cause the difference:

  • If the value of the operand is NaN or infinite, the result of the conversion is an unspecified value of the destination type. Otherwise, the source operand is rounded towards zero to the nearest integral value.
  • If this integral value is within the range of the destination type then this value is the result of the conversion.

The destination type here is the smaller int , and the value "-2147483648" that you're getting is the minimum value of a 32-bit signed integer. This suggests that the casting operation is converting the NaN to double.NegativeInfinity in order to perform an operation with it. The nearest integer to double.NegativeInfinity is int.MinValue , which is the value you're getting.

All of that said, the fact that this value is unspecified means that the result you get can depend on too many factors, right down to whether or not you assigned a variable or even what processor architecture you have. You're not supposed to use NaN casting to do anything meaningful, so NaN is never assigned an actual set value (largely because then it would, by definition, be a number). For most purposes, a NaN result should be treated as an error for this reason. The actual value is, in the end, meaningless.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM