a view of the Marsh

...: Chatter by Year

2014

March

February

2013

September

July

June

March

February

January

2012

December

November

October

September

August

July

June

May

April

March

February

January

2011

November

October

July

June

May

April

March

February

January

2010

December

November

October

September

August

July

June

May

April

March

February

January

2009

December

November

October

September

August

July

June

May

April

March

February

January

2008

December

November

October

September

August

...: Chatter by Keyword

ASP.NET

Browsers

Business

Cascading Styles (CSS)

Charity Work

Community

Definitions

Design

Education

Ethics

Firefox

First Post

Hockey

I.T. Events

Internet Explorer

Junk mailer/poster

Life

Microsoft

MS Access

Music

Other sports

Printers

Programming

sci-fi

Software

Speaking/Presentations

SQL

Survey

Teaching

The Marsh

Tips & Tricks

Tools of Trade

U.S. Events

Visual Basic (VB.NET)

Web Design

World Events

...: Marsh Chatter

When is Zero... Not Zero!

One thing that always "gets me", when writing code, is the handling of numbers in data types such as Double or Single (e.g. the .NET floating-point types). Yep, the simple stuff always comes back to haunt you. Let me explain...

I usually pick the larger data types for a "Divide by Zero" example in class (e.g. exception handling section). Yet, the handling of those data types results in behavior that always causes the pregnant pause with a question... "why did it just display Infinity, versus my Exception"? For class - it's great, because we get to explore the cause and effect. For work, it's one of those moments where you just slap yourself...

What's up with this?

The .NET floating point data types are based on IEEE standards, which is that floating point numbers are stored with large significant digit lengths and may not be what you expect -- ergo 0 (zero) may actually be represented in memory as 0.00000000...0001 -- where the ellipsis (...) is lots of zeros (and 1.0 could actually be stored as 0.99999...99999).

The end result is that when you divide by zero with this in-memory representation, you are really performing the Math rule 1/x - where x = a small number; mathematically this division = infinity, and not the exception we expected. For the floating-point data types, it kind of makes the "DivideByZeroException" useless (but wait... it has value with integer types).

For those interested, the following sites have more on this subject...

Not Just Divide By Zero... There's More!

Interestingly - testing these variables to see if they are zero returns "true". The following code example illustrates this. The "conditions" are shown performing an equivalency test. No division takes place.

Dim TheZeroAsVariable As Double = 0.0
Dim TheZeroViaConvert As Double = Convert.ToDouble("0.000")
Dim TheZeroViaParse As Double = Double.Parse("0.000")

Try
  If TheZeroAsVariable = 0.0 Then
    VarResultsLiteral.Text = "Variable: " & TheZeroAsVariable.ToString
  Else
    VarResultsLiteral.Text = (5.0 / TheZeroAsVariable).ToString
  End If

  If TheZeroViaConvert = 0.0 Then
    ConvertResultsLiteral.Text = "Convert: " & TheZeroViaConvert.ToString
  Else
    ConvertResultsLiteral.Text = (5.0 / TheZeroViaConvert).ToString
  End If

  If TheZeroViaParse = 0.0 Then
    ParseResultsLiteral.Text = "Parse: " & TheZeroViaParse.ToString
  Else
    ParseResultsLiteral.Text = (5.0 / TheZeroViaParse).ToString
  End If

  StatusLiteral.Text = "Results... 0 is 0 when you test it, but not when you use it."

Catch ex As DivideByZeroException
  StatusLiteral.Text = ex.Message
Catch ex As ArithmeticException
  StatusLiteral.Text = ex.Message
Catch ex As Exception
  StatusLiteral.Text = ex.Message
End Try

Results

The Zero is caught by the condition, not by Exception:

Variable: 0
Convert: 0
Parse: 0

Results... 0 is 0 when you test it, but not when you use it.

Does this ONLY affect Zero?

Now - just so you don't go thinking this only affects zero and that you're safe with other numbers. You're Not! The same issue would affect you if the number was 3, 100, or "bazillon". The floating-point data types will not represent the number "exactly" - hence your math or your conditions may not do what you are expecting.

Additionally, I wrote the example code with both types of converting methods - Convert and Parse, and the declared variable to show you that each of these do not have an affect on the results. It is all about the data type, not the converting method.

So What... do you do?

Pick a different data type.

  • Decimal is recommended by Microsoft for financial calculations.
  • If your result is not dependent on decimal places - use the Byte, Short, or Integer type data types.
  • If you need the additional digits (but not significant decimals) for your calculations, then stick with the Single or Double - just remind yourself to "watch your P's & Q's" with respect to these data types.

Back to writing code...