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

The fact that you can typecast Infinity to a long and get the finite result 9223372036854775808…

I think that is a bug.

By the way 3.5/0 equals positive infinity? From a mathematical point of view it could just as well be negative infinity (3.5/-0).

5(0 votes cast)@Martijn

Actually, it is not a bug but a feature ( it always is ). I’m not sure if you are familiar with the cehcked keyword but it is the key to the mistery.

Just try to place the cast into a checked {} block and you will notice the difference.

MSDN : If neither checked nor unchecked is used, a constant expression uses the default overflow checking at compile time, which is checked. Otherwise,

if the expression is non-constant, the run-time overflow checking depends on other factors such as compiler options and environment configuration.You can read about the checked keyword at MSDN C# Programmer’s Reference

5(0 votes cast)Very cool – I didn’t know you could do that. I guess that’s because I usually work with ints and decimals, not floats or doubles, so I really don’t ever see that.

I would say that instead of using all of those IsInfinity methods, the majority of data in most environments can and probably should be using decimals instead of floating-point types anyway – you don’t have to worry about the .9999999999 or .0000000001 “problems”, and this infinity situation wouldn’t occur either. Decimal’s range of values and significant digits should be enough for any financial or other real-world transaction, other than the serious scientific stuff.

5(0 votes cast)Thinking. It’s always the same thing. To think is to go crazy.

5(0 votes cast)Whoa!! I seriously didn’t know this!!! Thanks man!

5(2 votes cast)