Connecting Tech Pros Worldwide Help | Site Map

Using == with double data type

David Hoffer
Guest
 
Posts: n/a
#1: Nov 15 '05
Does C# have the same problem as C++ with code like this?

if (GetDouble1() == GetDouble2())
{
}

In C++, due to the IEEE storage format, it is possible to have 2 doubles
that are essentially the same value but not quite, so the above code will
not do what you expect. Boost has some extensions to STL to solve this
problem.

Does C# have similar problems? If so, what is the right C# way of handling
this issue?

-dh


Randy A. Ynchausti
Guest
 
Posts: n/a
#2: Nov 15 '05

re: Using == with double data type


David,
[color=blue]
> Does C# have the same problem as C++ with code like this?
>
> if (GetDouble1() == GetDouble2())
> {
> }
>
> In C++, due to the IEEE storage format, it is possible to have 2 doubles
> that are essentially the same value but not quite, so the above code will
> not do what you expect. Boost has some extensions to STL to solve this
> problem.
>
> Does C# have similar problems? If so, what is the right C# way of[/color]
handling[color=blue]
> this issue?[/color]

Yes, floating-point (not just double precision) numbers/arithmethic has this
problem in virtually every language because of the representation that you
have noted. One way of handling this is to calculate the precision of the
machine that your code is running on and then do a comparison to see if the
difference is less than or equal to the precision of the machine. If it is,
then the values are identical as far as you can tell.

Note that C# has the "Decimal" type that can help is many situations.

Regards,

Randy


Dmitriy Lapshin [C# / .NET MVP]
Guest
 
Posts: n/a
#3: Nov 15 '05

re: Using == with double data type


David, Randy,

One could also introduce some "delta" value and consider the values equal if
their difference is smaller than the delta. The delta can obviously be the
machine precision but it can also be bigger.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Randy A. Ynchausti" <randy_ynchausti@msn.com> wrote in message
news:uY3bYwZrDHA.920@TK2MSFTNGP10.phx.gbl...[color=blue]
> David,
>[color=green]
> > Does C# have the same problem as C++ with code like this?
> >
> > if (GetDouble1() == GetDouble2())
> > {
> > }
> >
> > In C++, due to the IEEE storage format, it is possible to have 2 doubles
> > that are essentially the same value but not quite, so the above code[/color][/color]
will[color=blue][color=green]
> > not do what you expect. Boost has some extensions to STL to solve this
> > problem.
> >
> > Does C# have similar problems? If so, what is the right C# way of[/color]
> handling[color=green]
> > this issue?[/color]
>
> Yes, floating-point (not just double precision) numbers/arithmethic has[/color]
this[color=blue]
> problem in virtually every language because of the representation that you
> have noted. One way of handling this is to calculate the precision of the
> machine that your code is running on and then do a comparison to see if[/color]
the[color=blue]
> difference is less than or equal to the precision of the machine. If it[/color]
is,[color=blue]
> then the values are identical as far as you can tell.
>
> Note that C# has the "Decimal" type that can help is many situations.
>
> Regards,
>
> Randy
>
>[/color]

David Hoffer
Guest
 
Posts: n/a
#4: Nov 15 '05

re: Using == with double data type


Thanks for the reply, how do I determine the precision of the machine?
Also, since everybody has this problem, is there any code libraries
available (C# extensions) that deal with this? This seems like something
that Microsoft would address...

-dh

"Randy A. Ynchausti" <randy_ynchausti@msn.com> wrote in message
news:uY3bYwZrDHA.920@TK2MSFTNGP10.phx.gbl...[color=blue]
> David,
>[color=green]
> > Does C# have the same problem as C++ with code like this?
> >
> > if (GetDouble1() == GetDouble2())
> > {
> > }
> >
> > In C++, due to the IEEE storage format, it is possible to have 2 doubles
> > that are essentially the same value but not quite, so the above code[/color][/color]
will[color=blue][color=green]
> > not do what you expect. Boost has some extensions to STL to solve this
> > problem.
> >
> > Does C# have similar problems? If so, what is the right C# way of[/color]
> handling[color=green]
> > this issue?[/color]
>
> Yes, floating-point (not just double precision) numbers/arithmethic has[/color]
this[color=blue]
> problem in virtually every language because of the representation that you
> have noted. One way of handling this is to calculate the precision of the
> machine that your code is running on and then do a comparison to see if[/color]
the[color=blue]
> difference is less than or equal to the precision of the machine. If it[/color]
is,[color=blue]
> then the values are identical as far as you can tell.
>
> Note that C# has the "Decimal" type that can help is many situations.
>
> Regards,
>
> Randy
>
>[/color]


J.Marsch
Guest
 
Posts: n/a
#5: Nov 15 '05

re: Using == with double data type


Check out Double.Epsilon Right now, it's a constant value. Theoretically,
if they port .Net to a different architecture, where the precision is
different, the value of Epsilon will change as well.

You should be able to do something like:

if(Math.Abs(GetDouble1() - GetDouble2()) < Double.Epsilon)
{
// they are "equal" -- sort of
}


"David Hoffer" <dhoffer.remove@xrite.remove.com> wrote in message
news:uHnkQkdrDHA.920@TK2MSFTNGP10.phx.gbl...[color=blue]
> Thanks for the reply, how do I determine the precision of the machine?
> Also, since everybody has this problem, is there any code libraries
> available (C# extensions) that deal with this? This seems like something
> that Microsoft would address...
>
> -dh
>
> "Randy A. Ynchausti" <randy_ynchausti@msn.com> wrote in message
> news:uY3bYwZrDHA.920@TK2MSFTNGP10.phx.gbl...[color=green]
> > David,
> >[color=darkred]
> > > Does C# have the same problem as C++ with code like this?
> > >
> > > if (GetDouble1() == GetDouble2())
> > > {
> > > }
> > >
> > > In C++, due to the IEEE storage format, it is possible to have 2[/color][/color][/color]
doubles[color=blue][color=green][color=darkred]
> > > that are essentially the same value but not quite, so the above code[/color][/color]
> will[color=green][color=darkred]
> > > not do what you expect. Boost has some extensions to STL to solve[/color][/color][/color]
this[color=blue][color=green][color=darkred]
> > > problem.
> > >
> > > Does C# have similar problems? If so, what is the right C# way of[/color]
> > handling[color=darkred]
> > > this issue?[/color]
> >
> > Yes, floating-point (not just double precision) numbers/arithmethic has[/color]
> this[color=green]
> > problem in virtually every language because of the representation that[/color][/color]
you[color=blue][color=green]
> > have noted. One way of handling this is to calculate the precision of[/color][/color]
the[color=blue][color=green]
> > machine that your code is running on and then do a comparison to see if[/color]
> the[color=green]
> > difference is less than or equal to the precision of the machine. If it[/color]
> is,[color=green]
> > then the values are identical as far as you can tell.
> >
> > Note that C# has the "Decimal" type that can help is many situations.
> >
> > Regards,
> >
> > Randy
> >
> >[/color]
>
>[/color]


Randy A. Ynchausti
Guest
 
Posts: n/a
#6: Nov 15 '05

re: Using == with double data type


David,
[color=blue]
> Thanks for the reply, how do I determine the precision of the machine?
> Also, since everybody has this problem, is there any code libraries
> available (C# extensions) that deal with this? This seems like something
> that Microsoft would address...[/color]

See code in books such as Numerical Recipies, Numerical Algorithms in
Smalltalk and Java, etc. Here is a start:

private static System.Int64 radix = 0;
private static System.Double machinePrecision = 0.0D;

private static void ComputeRadix( )
{
System.Double anA = 1.0D, aB = 1.0D, aTemp1, aTemp2;
do
{
anA += anA;
aTemp1 = anA + 1.0D;
aTemp2 = aTemp1 - anA;
}
while( aTemp2 - 1.0D != 0.0D );
while( radix == 0 )
{
aB += aB;
aTemp1 = anA + aB;
radix = ( System.Int64 ) ( aTemp1 - anA );
}
}

private static void ComputeMachinePrecision( )
{
System.Double aFloatingRadix = ComputeRadix( );
System.Double anInverseRadix = 1.0D / aFloatingRadix;
machinePrecision = 1.0D;
System.Double aTempPrecision = 1.0D + machinePrecision;
while( ( aTempPrecision - 1.0D ) != 0.0D )
{
machinePrecision *= anInverseRadix;
aTempPrecision = 1.0D + machinePrecision;
}
}

Note that you may want to compute the precision from the negative side too.

Regards,

Randy


Randy A. Ynchausti
Guest
 
Posts: n/a
#7: Nov 15 '05

re: Using == with double data type


David,

By the way, my machine reports the following:

Floating-Point Calculation Parameters:
--------------------------------------
Radix : 2
Machine Precision : 1.11022302462516E-16
Negative Machine Precision : 5.55111512312578E-17
Smallest Number : 4.94065645841247E-324
Largest Number : 1.79769313486232E+308

So any two floating point numbers that are less than 1.11022302462516E-16
apart are essentially equal.

Regards,

Randy


Closed Thread