The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

Hi EE,

I have a piece of code, it's working most of the time, however it some time throw 'attempt to divide by zero' error, although I did have a check for zero on the denominator before the divide, wonder what the problem is, if anyone has any idea please let me know.

I have a piece of code, it's working most of the time, however it some time throw 'attempt to divide by zero' error, although I did have a check for zero on the denominator before the divide, wonder what the problem is, if anyone has any idea please let me know.

```
Dim myDenominator As Decimal = (CDec(Math.Round(row("TotQty"), 2)) + CDec(Math.Round(row("DelQty"), 2)))
If (myDenominator <> 0) Then
Dim newStdCost As Decimal = (((CDec(Math.Round(row("TotQty"), 2)) * CDec(Math.Round(row("StdCost"), 2))) + (CDec(Math.Round(row("DelQty"), 2)) * CDec(Math.Round(row("DelCost"), 2))))) / myDenominator
End If
```

When you assign the value to your denominator, you end up with only 2 decimal. And the multiplication ends up with 6 at most. There is no need for all the extras that the Decimal type provides.

Because the number of decimal places in the Decimal type is variable, Decimal values are handled in a special way compared to the more straightforward Single and Double type.

I would try removing all the CDec and work with a Double all the way. Convert only the result to Decimal if you really need that data type for other operations.

could you let me know how double and decimal are handled differently? i see this is a good chance of learning something I didn't know before.

James, as a developer of financial applications, I can tell you that I use Decimal types for all of my currency values. The reason is that it's too easy for rounding errors to creep in otherwise. It may not seem like a big deal what's happening to that extra cent, but it makes accountants go crazy; they want numbers to tie out exactly. I go to a lot of effort to make sure that, for instance, if a one dollar asset is depreciated over three months, I get back to a dollar, not 99 cents. The other issue is that getting a spurious 1 millionth or whatever can cause comparisons to go haywire: if .33 + .37, because of the imprecision of floating point arithmetic, turns into .70000000000001, that doesn't equal .7, and you can run into really nasty debugging projects and extra verifications required all over the place. (Even more commonly at issue, .00000000001 <> 0.)

Decimal is a bit more processor-intensive, to be sure, but in my opinion it's well worth it. If the alternative is doing a Math.Round() call every time you add and subtract, you're probably ahead of the game.

I never had to deal with those precisions in my applications, where woodworkers often find that 1/64 is too much precision in my current project, and where money operations in my older projects were almost of the multiplying a quantity by a unit price and adding the taxes sort. And my own accoutant is OK as long as we follow the rounding rules of the canadian government that do not got further than a few decimals. My bank does not care either, interests on my 25 years mortgage were rounded out at the 4th decimal.

Having the input from a programmer who has another experience is always a good learning lesson.

yes I'm sure it was the line throwing the error.

there are further calculations after that however none of them have a divide so i took them out in the post above.

the funny thing is it is not always throwing the error, happens 1 - 2 times everyday. i tried to record the product it had the issue and went back checked, everything looked normal.

maybe there's something else going wrong?

If you're getting it 1-2 times a day, I presume this is an application that's in production. Since it's intermittent, just running in debug won't likely help you much. But I think you need to get some debugging information out of the application. My first step would probably be to put the Dim newStdCost statement in a Try/Catch block. If the exception fires, display ALL the values that are in the calculation on that line. If you get the error and the Catch isn't triggered, it tells you that the problem is somewhere else; perhaps you can set up another Try/Catch block for the rest of the code and display enough information in the error message to tell you how far it got before crashing.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.

The Double is a 64-bit number. 32 for the integer part, 32 for the decimal. The number of decimals is thus fixed at 15.

The Decimal is a 128-bit number. However, contrary to the other 2 types of floats, the number of bits assigned to the integer part and the decimal part is variable. If you have a value of 0, no bit is used for the integer part, and all of the 128 bits are used for the decimal part, giving you 28 decimal places. As the integer part grows, the number of bits available for the decimal part is reduced, an you thus lose decimal places. A very big number (either negative or positive) will thus have less decimal precision than a small one.

I do not know about the implementation details, but it is clear that this mechanism of having a variable lenght for the integer vs decimal parts of a value involves some internal manipulations that are not necessary in a Double that has a fixed memory footprint for the 2 values. What is clear also is that the Decimal type incurs a hit on performance. So, unless you really need the extra precision (over 15 decimals), you are better to stay clear of that type.

Now, a question of my own. I would be glad to have somebody jump in and explain that to me.

The documentation for Decimal states that the Decimal type "is particularly suitable for calculations, such as financial, that require a large number of digits but cannot tolerate rounding errors". This is confirmed somewhat by the fact that when you convert a VB6 application to .NET, the old Currency type (that is not available anymore) is converted to Decimal. I greatly suspect that your use of the Decimal type could come from such a conversion.

But although I never had to code financial applications, in my experience most financial operations round off at 4 decimals (this is what the old Currency type did). When I bought my house, I checked the interests charged by the bank and came out with a higher amount than the bank did. It made a difference of $25 a month on my paiement. I was working with Single values, 7 decimals. When I adjusted to 4, I came out with only 1 cent of difference... and figure out who was getting the extra cent?

I know that some finalcial operations, such as currency exchange, round off at 5 decimals. So, why this statement about Decimal suitable for financial calculations. A Single is quite capable of working at that level, and a Double twice more so.

As far as I am concerned, Decimal could be useful for some scientific calculations, say at the level of the atom or the universe. But even there, it is often too much. I had to do something dealing with chemistry for a pharmacology company many years ago, and the Double, with its 15 decimals of precision, was enough for them.

So, could somebody tells me what types of financial operations would require the Decimal type?