.1 + .2 = 0.30000000000000004

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

In the below code, mOnePlusTwo evaluates to 0.30000000000000004 (although it
displays as ".3"). Consequently, comparing that value to mThree (.3) results
in false.

What's going on? Is there something else I should do (other than switch to
using decimal types)?

double mOne = .1;
double mTwo = .2;
double mThree = .3;
double mOnePlusTwo = mOne + mTwo;

bool mEqual = false;
if (mOnePlusTwo == mThree)
{
mEqual = true;
}

Console.WriteLine("mOne = " + mOne);
Console.WriteLine("mTwo = " + mTwo);
Console.WriteLine("mThree = " + mThree);
Console.WriteLine("mOnePlusTwo = " + mOnePlusTwo);
Console.WriteLine("mThree == mOnePlusTwo? = " + mEqual);
 
Craig said:
In the below code, mOnePlusTwo evaluates to 0.30000000000000004
(although it displays as ".3"). Consequently, comparing that value
to mThree (.3) results in false.

What's going on? Is there something else I should do (other than
switch to using decimal types)?

Switch to decimal and read this article:

What Every Computer Scientist Should Know About Floating-Point Arithmetic
http://docs.sun.com/source/806-3568/ncg_goldberg.html

--
Reginald Blue
"I have always wished that my computer would be as easy to use as my
telephone. My wish has come true. I no longer know how to use my
telephone."
- Bjarne Stroustrup (originator of C++) [quoted at the 2003
International Conference on Intelligent User Interfaces]
 
Double or float number always has a precision up to certain digits. In
other word, there is a rounding error. You should never compare to
doubles for equal. To compare doubles:
double epsilon = .0000000001; // a precision you like up to double
can have.
if (Math.Abs(mOnePlusTwo - mThree) < epsilon)
true part
else
false part
 
This is entirely correct.

In base 10, the rational number 1 divided by the rational number 3 yeilds a
repeating decimal value 0.333333333333333. It is not accurately
represented.
In base 2, the same number (1/3) is not a repeating radix value. It is
accurately represented.

In base 2, the rational number 1 divided by the rational number 10 (1/10)
yeilds a repeating radix value. It is not accurately represented.

Since 0.1 cannot be accurately represented in binary, we don't try. We use
decimal notation which is a representation of the digits, not the number.

If you are making statistical calcuations, use double. For currency or
values where multiples of 1/10 are important, use decimal.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
 
Nick Malik said:
In base 2, the same number (1/3) is not a repeating radix value. It is
accurately represented.

No it isn't - *anything* which can't be accurately represented as a
non-recurring decimal can't be accurately represented as a binary
number either. (Conversely, everything which can be represented exactly
as binary can be represented exactly in decimal.)
 
Craig said:
In the below code, mOnePlusTwo evaluates to 0.30000000000000004 (although it
displays as ".3"). Consequently, comparing that value to mThree (.3) results
in false.

You need to round your numbers
no alternative
several ways to do this
you need to be careful
compare the two writes.

using System;

namespace trial1
{

class Class1
{

[STAThread]
static void Main(string[] args)
{
double dbl1 = .333333333333333;
double dbl2 = .4444444444444444;

double dbl3 = round(dbl1)+round(dbl2);

//Console.WriteLine(round(dbl1 + dbl2).ToString());

Console.WriteLine(round(dbl3).ToString());
}

static double round(double dbl)
{
//return Math.Round(dbl,2);
//return Convert.ToDouble(dbl.ToString("########.##"));
//return Convert.ToDouble(dbl.ToString("N"));
//return Convert.ToDouble( String.Format("{0:N}",dbl));
return Convert.ToDouble(String.Format("{0:F}",dbl));
}

}
}
 
if you use the decimal datatype, you do not need to round the numbers

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
Zach said:
Craig said:
In the below code, mOnePlusTwo evaluates to 0.30000000000000004 (although it
displays as ".3"). Consequently, comparing that value to mThree (.3) results
in false.

You need to round your numbers
no alternative
several ways to do this
you need to be careful
compare the two writes.

using System;

namespace trial1
{

class Class1
{

[STAThread]
static void Main(string[] args)
{
double dbl1 = .333333333333333;
double dbl2 = .4444444444444444;

double dbl3 = round(dbl1)+round(dbl2);

//Console.WriteLine(round(dbl1 + dbl2).ToString());

Console.WriteLine(round(dbl3).ToString());
}

static double round(double dbl)
{
//return Math.Round(dbl,2);
//return Convert.ToDouble(dbl.ToString("########.##"));
//return Convert.ToDouble(dbl.ToString("N"));
//return Convert.ToDouble( String.Format("{0:N}",dbl));
return Convert.ToDouble(String.Format("{0:F}",dbl));
}

}
}
 
Nick Malik said:
if you use the decimal datatype, you do not need to round the numbers

Unless you do anything which potentially leads to a result which can't
be accurately represented in decimal - like dividing 1 by 3, for
example.
 
Hi !
Jon Skeet wrote:
[...snip...]
Unless you do anything which potentially leads to a result which can't
be accurately represented in decimal - like dividing 1 by 3, for
example.
[...snip...]

Do you know any .net maths library implementing a Fraction class to be able
to perform accurate fraction calculation ?
 
Michael Voss said:
Jon Skeet wrote:
[...snip...]
Unless you do anything which potentially leads to a result which can't
be accurately represented in decimal - like dividing 1 by 3, for
example.
[...snip...]

Do you know any .net maths library implementing a Fraction class to be able
to perform accurate fraction calculation ?

I don't, I'm afraid - I'm pretty sure there's one out there, but I
can't remember the name.
 
Back
Top