Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Double.MaxValue to integer is negative?

Tags:

Why does Double.MaxValue casted to an integral type results in a negative value, the smallest value of that type?

double maxDouble = double.MaxValue;       // 1.7976931348623157E+308 long maxDoubleLong = (long) maxDouble;    // -9223372036854775808 

I'd understand a compiler error if it's too large or an OverflowException at runtime or if i'd use unchecked that the conversion might not throw an exception, but the result becomes undefined and incorrect(negative).

Also strange is that the value is long.MinValue:

bool sameAsLongMin = maxDoubleLong == long.MinValue; // true 

By the way, the same happens if i cast it to int:

int maxDoubleInt = (int)maxDouble;                   // -2147483648 bool sameAsIntMin = maxDoubleInt == int.MinValue;    // true 

If it try to cast it to decimal i get an OverflowException at runtime

decimal maxDoubleDec = (decimal)maxDouble;  // nope 

Update: it seems that Michael's and Barre's answers hit the nail on the head, if i use checked explicitly i get an OverflowException:

checked {     double maxDouble = double.MaxValue;     // 1.7976931348623157E+308     long maxDoubleLong = (long) maxDouble;  // nope } 
like image 577
Tim Schmelter Avatar asked Mar 31 '14 08:03

Tim Schmelter


People also ask

What is double MaxValue in C#?

Represents the largest possible value of a Double. This field is constant. public: double MaxValue = 1.7976931348623157E+308; C# Copy.

What is a busted max value?

Returns The min Value Integer can hold is -2147483648 The Maximum Value Integer can hold is 2147483647 The BUSTED MAX INT value is -2147483648 The BUSTED Min INT value is 2147483647 The min Value Byte can hold is -128 The Maximum Value Byte can hold is 127 The BUSTED MAX Byte value is 128 The BUSTED Min Byte value is - ...


1 Answers

The C# Language Specification (Version 5.0) says the following in 6.2.1 "Explicit numeric conversions" (emphasis added):

  • For a conversion from float or double to an integral type, the processing depends on the overflow checking context (§7.6.12) in which the conversion takes place:

    • 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.

And in 7.6.12 "The checked and unchecked operators"

For non-constant expressions (expressions that are evaluated at run-time) that are not enclosed by any checked or unchecked operators or statements, the default overflow checking context is unchecked unless external factors (such as compiler switches and execution environment configuration) call for checked evaluation.

For conversions from double to decimal: "If the source value is NaN, infinity, or too large to represent as a decimal, a System.OverflowException is thrown". checked vs unchecked doesn't come into play (those deal with integral operations only).

like image 126
Michael Burr Avatar answered Oct 06 '22 18:10

Michael Burr