Division by zero is simple, isn’t it ?
I’m sure you all know that according to the rules of elementary arithmetic division by zero is not allowed*. Also, I’m pretty sure you are familiar with the “Attempted to divide by zero” exception and some of you even write a specific catch in try…catch blocks to catch the DivideByZeroException to be able to handle it according to your application needs.
A few days ago I had to solve some very ugly bug that was caused by exactly the same approach I mentioned.
The code contained some calculation with a very large numbers and some how the results weren’t close to what we expected.
Let’s see some code
// Example #2 var firstValue = 3; var secondValue = 0; var result = firstValue / secondValue;
Simple, isn’t it. Running the above code will throw DivideByZeroException exception as we all expected.
Now look at the following code. Will it behave the same way ?
// Example #2 var firstValue = 3.5; var secondValue = 0; var result = firstValue / secondValue;
As you probably suspected – it won’t. It will run and complete without throwing any exception at all.
So, what happened here ? Are we talking about some serious bug Microsoft isn’t aware of ?
Well, first of all it is not a bug. The difference between the two examples is the type we are trying to divide by zero. In the first example firstValue is an Integer and in the second example is Double.
Does that mean we can divide floating point numbers by zero ? Yes we can.
Now you are probably wondering what will be the the value of result. Well, the answer is – Infinity. Yes, there is a value called Infinity and to be more specific, in our case the result is a Positive Infinity. The interesting part is because Infinity is a value you can make calculations with it and it won’t throw any exception. Let’s see some examples :
var i = 3.5 / 0; // Infinity var t1 = i++; // Infinity var t2 = i--; // Infinity var t3 = i/i; // NaN var t4 = i * i; // Infinity var t5 = i>0; // true var t6 = i > double.MaxValue; // true var t7 = double.MaxValue - i; // -Infinity [ Negative Infinity ] var t8 = i-i; // NaN
So, now we know that calculations using Infinity are possible but in most cases the result won’t be something you can use for further calculation. By the way, if you will try to insert Infinity into Microsoft SQL field (at least in 2005) it will throw an exception saying “The supplied value is not a valid instance of data type float”.
And now i would like to return to the bug i was talking about at the beginning of this post.
What do you think will be the result of the following code.
var i = 3.5 / 0; var result = (long)i;
The result is very numeric, not NaN and not Infinite but -9223372036854775808.
Now imagine situation when you must calculate some numbers that represent money, I mean loans, balance, etc. I’m sure you can easily understand how far can it go and which unpleasant result we can get.
C# provide us some usefull functions and constants we can and must use to avoid the above mistakes.
// Returns a value indicating whether the specified number // evaluates to negative or positive infinity double.IsInfinity(double d) // Returns a value indicating whether the specified number // evaluates to negative infinity. double.IsNegativeInfinity (double d) // Returns a value indicating whether the specified number // evaluates to positive infinity. double.IsPositiveInfinity (double d) // Represents negative infinity. This field is constant. double.NegativeInfinity // Represents positive infinity. This field is constant. double.PositiveInfinity // Represents a value that is not a number (NaN). // This field is constant. double.NaN
Floating point is necessary in so many cases – use it wisely and carefully.