#1,098 – Floating Point Overflow

When you perform an arithmetic operation on a floating point value and the result has a magnitude that is too large to be represented by the floating point data type, an overflow condition occurs.  This is equivalent to trying to store a value whose exponent is larger than the maximum allowed exponent value.

If the result of the calculation is greater than the maximum representable positive floating point value, the result of the calculation is +Infinity.  If the result of the calculation is less than the largest representable negative floating point value, the result of the calculation is -Infinity.

            // Create a big floating point number
            float bigNumber = float.MaxValue;
            Console.WriteLine(bigNumber);  // 3.402823E+38

            // Adding small number doesn't change large number
            float newBig = bigNumber + 1.0f;
            Console.WriteLine(newBig);     // 3.402823E+38

            // But doubling the original number leads to overflow
            float reallyBig = bigNumber * 2.0f;



#1,072 – How the Unary Minus Operator Can Fail

There are cases when applying a unary operator to an operand results in a value that does not fit into the data type of the operand. Consider the int type, whose range is -2,147,483,648 to 2,147,483,647.  If we assign the minimum value (largest negative number) and try to negate it with the unary operator, the negation will fail.

By default, arithmetic operations work in an unchecked context.  In this case, the unary operator does nothing, just returning the value of the original operand.

            // int range is -2,147,483,648 to 2,147,483,647
            int n = int.MinValue;
            n = -n;  // n unchanged

If we do the same operation in a checked context, we’ll get an overflow exception.



Note that a cast to a “larger” data type fails if it’s done outside of the unary operator.  But casting before applying the operator does work.

            long l = (long)-n;  // Still fails

            long l2 = -(long)n;  // This works


#57 – Overflow on Integer Operations

When executing arithmetic operations on integer-based types, an overflow can occur when the result of the operation cannot be stored in the destination type.

By default in C#.NET, when overflow occurs for integer-based types, the most significant bits of the result are discarded.  Effectively, this results in the value appearing to wrap.  E.g. Large values wrap to smaller (or large negative for unsigned) values.

Here are some examples of wrapping on integer-based overflow.

 uint u1 = 0xffffffff;
 u1 = u1 + 5;       // Now 0x00000004 (wrapped)

 int n1 = int.MaxValue;      // 2147483647 (0x7FFFFFFF)
 n1 = n1 + 1;                // Now -2147483648 (wrapped)

 short s1 = short.MinValue;
 s1 = (short)(s1 - 1);       // Now 32767 (wrapped)