Artimetic bug in .Net

Posted on 2006-11-13
Last Modified: 2010-04-24
It seems that .Net cannot make some simple numerical operations.

Try to write this in the debugger:
587.67 + 146.67

The result should be 734.34, but .Net calculates it to (586.67 + 146.67 = 733.33999999999992 Double)

Can somebody explain to me why?

I've found also other similar bugs but I think that showing one is enough.
Question by:fulgeru99
LVL 10

Expert Comment

ID: 17928781
Running console.WriteLine(587.67 + 146.67) produces the right result.

Where are you running this ? and what version of vs are you using ?

Author Comment

ID: 17928841
Yes, if you write something like this is DISPLAYS correctly:

Sub Main()
    Dim sum As Double = 587.67 + 146.67
End Sub

But calling the WriteLine functions actualy calls Double.ToString() that formats the number and that seems to work. However, I am not using the ToString() function. I am calculating a sum in a foreach loop and then I am comparing it to another variable.

The problem is the way .Net internally stores that result.

Make the following checks also:
a) put a breakpoint on the line Console.WriteLine(sum) and add a watch for the variable sum
b) try this piece of code:
 Sub Main()
    Dim sum As Double = 587.67 + 146.67
    Dim damnIt As Boolean = (734.34 = sum)

  End Sub

LVL 34

Accepted Solution

Sancler earned 200 total points
ID: 17928931
Unless your numbers are too large, or performance is crucial (and in that case, I am not sure that any of the alternatives - such as

    Dim damnIt As Boolean = (734.34 = sum.ToString)

- would be faster), it sounds like you want to use the Decimal datatype rather than the Double.

From the documentation

The Decimal data type provides the greatest number of significant digits for a number. It supports up to 29 significant digits and can represent values in excess of 7.9228 x 10^28. It is particularly suitable for calculations, such as financial, that require a large number of digits but cannot tolerate rounding errors.

The default value of Decimal is 0.

Programming Tips
Precision. Decimal is not a floating-point data type. The Decimal structure holds a binary integer value, together with a sign bit and an integer scaling factor that specifies what portion of the value is a decimal fraction. Because of this, Decimal numbers have a more precise representation in memory than floating-point types (Single and Double).

Performance. The Decimal data type is the slowest of all the numeric types. You should weigh the importance of precision against performance before choosing a data type.

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

LVL 19

Assisted Solution

VoteyDisciple earned 50 total points
ID: 17929336
It sounds like you're just seeing the messy internals of the IEEE-754 floating-point standard.  Just like there are numbers that we can't accurately express in decimal format (like 1/3, for instance) there are numbers that we can't accuraetly express in IEEE-754 notation, which is essentially just a binary decimal format.

Take a look at some of the references/toys here:

This is definitely not unique to .NET; it's common to how all computers process floating-point numbers.  

As Sancler suggests, the workaround when decimal precison matters the Decimal format is more appropriate.  It makes no attempt to convert your decimal floating-point numbers to binary floating-point numbers, but rather stores each digit separately.  There is, thus, no chance of rounding errors in conversion.

Author Comment

ID: 17929588
On this example, having the variable Decimal works.
However, I remember that I found a bug in Decimal also.

Anyway, try this: start debugging and add a new watch were you write: 587.674 + 146.67
No data type, just the calculation and see the result.

Moreover, type ?587.674 + 146.67 in the immediate output window.

Can anyone explain why?

I found that there are some special cases on some special sums where the calculation is wrong.

Expert Comment

ID: 17930832
This how this is showing in , but you will lose anything. this is how they storing as bits. in many times, if ur number is ending 1 4 or 8,you may get this lengthy result. But this is NOT true for many cases.

But you use round function, u will not lose anything.


Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
No row return after calling the fillschema method 4 46 checkbox 7 46
Change Format on Data when exporting to Excel 4 32
VB.NET (2008) - Refactoring Question 2 19
This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question