## digitalmars.D - Comparing double and float values

• Abid H. Mujtaba (15/15) May 12 2011 I am working through "The D Programming Language" by Andrei
• Alexander (6/13) May 12 2011 Quite OK, IMHO:
• Matthew Ong (9/9) May 12 2011 Hi Alexander,
• Jens Mueller (9/21) May 12 2011 That's sounds a bit odd to me. I thought that in application code you
• Alexander (8/12) May 12 2011 The problem is that not every decimal value may be stored with the sam...
• Don (5/19) May 13 2011 std.math.isIdentical().
• Abid H. Mujtaba (4/4) May 12 2011 Thanks for the answer. I guess the correct technique would be to
• Andrei Alexandrescu (4/8) May 12 2011 Thanks for considering adding to the errata. Which particular example on...
• Abid H. Mujtaba (20/20) May 12 2011 Section 5.5 Overloading on page 142 it defines the following example
• Andrei Alexandrescu (3/7) May 12 2011 Also, you may want to peruse the function approxEqual in std.math.
Abid H. Mujtaba <abid.naqvi83 gmail.com> writes:
```I am working through "The D Programming Language" by Andrei
Alexandrescu and one of the examples compared an array of doubles
with an array of floats in a unittest (pg. 143 while discussing
using rdmd. I simplified the problem and the following code will not
compile:

// Code in file test.d

unittest
{
double x = 3.2 ;
float y = 3.2 ;

assert( x == y ) ;
}

Running 'rdmd --main -unittest test.d' results in:

core.exception.AssertError test(6): unittest failure
```
May 12 2011
Alexander <aldem+dmars nk7.net> writes:
```On 12.05.2011 10:03, Abid H. Mujtaba wrote:

unittest
{
double x = 3.2 ;
float y = 3.2 ;

assert( x == y ) ;
}

Quite OK, IMHO:

x-y = -4.76837e-08

Just regular rounding error, and we are comparing values stored with
different precision.

Float values quite rarely can store *exact* values.

/Alexander
```
May 12 2011
Matthew Ong <ongbp yahoo.com> writes:
```Hi Alexander,

Is there anyway to ensure the comparison of float/double to be done with the raw
bits like in Java
Double.doubleToRawLongBits(double value)

when it comes to financial data and percentage computation, that seems to be
rather important.

Matthew Ong
```
May 12 2011
Jens Mueller <jens.k.mueller gmx.de> writes:
```Matthew Ong wrote:
Hi Alexander,

Is there anyway to ensure the comparison of float/double to be done with the
raw
bits like in Java
Double.doubleToRawLongBits(double value)

when it comes to financial data and percentage computation, that seems to be
rather important.

That's sounds a bit odd to me. I thought that in application code you
should never compare floating points regarding equality. I only know of
something similar in testing code where you compare equality within some
number of ulps (unit of least precision). So your use case sounds
interesting. Can you elaborate a bit?
If you really want to to compare bit by bit it should be possible to
cast the floating point values and then perform the comparison.

Jens
```
May 12 2011
Matthew Ong <ongbp yahoo.com> writes:
```Hi jen,

If you really want to to compare bit by bit it should be possible to
cast the floating point values and then perform the comparison.

Casting does that looses the value decimal point value?

The most important
Returns a representation of the specified floating-point value according to the
IEEE 754 floating-point "double format" bit layout, preserving Not-a-Number
(NaN)
values.

underneath the source code, it is just C code:

union {
double dval;
long lval;
}

They fill dval to get lval and vs.

That is important if u use that for searching within a Hashtable like:

double[string] myvals; // look for the key string using double?
```
May 12 2011
Alexander <aldem+dmars nk7.net> writes:
```On 12.05.2011 12:08, Matthew Ong wrote:

Is there anyway to ensure the comparison of float/double to be done with the
raw
bits like in Java
Double.doubleToRawLongBits(double value)

The problem is that not every decimal value may be stored with the same bits
in float or double, again, due to rounding and other errors.

Try it for yourself: http://babbage.cs.qc.edu/IEEE-754/Decimal.html

Sure, for simple cases, when no operations are performed and values are
simply stored, doubles/floats *may* be sufficient, but anything more important
- and errors will accumulate very quickly.

when it comes to financial data and percentage computation, that seems to be
rather important.

When it comes to financial data, where you really need *exact* calculations
within given precision, forget about standard floating point formats.

Instead, you should use something like http://www.mpfr.org/#intro - with
exact and guaranteed precision.

Alternatively, you may use something like std.bignum in Phobos with
artificial fixed point position (if you need the fast way to go with D).

/Alexander
```
May 12 2011
Matthew Ong <ongbp yahoo.com> writes:
```Hi Alex,

Coming from a Java 1.6 environment and ex-CPP.

http://www.prowiki.org/wiki4d/wiki.cgi?JavaToD
decimal point number without the use of a library like other language.

Avoiding runtime error like:
d1=func1(); // returns -0.0i;
d2=func2(); // return 0.0i;

if(d1==d2)... // some time that failed.
```
May 12 2011
Don <nospam nospam.com> writes:
```Matthew Ong wrote:
Hi Alexander,

Is there anyway to ensure the comparison of float/double to be done with the
raw
bits like in Java
Double.doubleToRawLongBits(double value)

when it comes to financial data and percentage computation, that seems to be
rather important.

Matthew Ong

std.math.isIdentical().
I doubt it would ever be appropriate to use this in a financial context,
it's more for precise testing of math functions.
Note that, for example, isIdentical(-0.0, +0.0) returns false.
```
May 13 2011
Matthew Ong <ongbp yahoo.com> writes:
```On 5/13/2011 3:12 PM, Don wrote:
std.math.isIdentical().
I doubt it would ever be appropriate to use this in a financial context,
it's more for precise testing of math functions.
Note that, for example, isIdentical(-0.0, +0.0) returns false.

Hi,

Hmm.. That is main reason that I can see that why Java provided that
function. Thanks. I will keep that in mind.

In Java and most C/C++ does not have problem for <,>, for double/float
type comparison. But when it comes to <=,>=,== we need to be very
careful and need to somehow solve that with some sort of raw bits
method. I cannot remember, there is one programming language(old one)
does not have issue when it comes to financial data computation and also
logical comparison. To handle that I have written some API in Java,
looks like I need to port that over also. But let me bounce that off
other to see if there is someone that have solved this before.

--
Matthew Ong
email: ongbp yahoo.com
```
May 16 2011
Abid H. Mujtaba <abid.naqvi83 gmail.com> writes:
```Thanks for the answer. I guess the correct technique would be to
define an "equality" function with a tolerance within 1e-08. I guess I
should head over to the TDLP errata section and point out that the
example code needs to be fixed to allow for this possibility.
```
May 12 2011
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
```On 5/12/11 11:00 AM, Abid H. Mujtaba wrote:
Thanks for the answer. I guess the correct technique would be to
define an "equality" function with a tolerance within 1e-08. I guess I
should head over to the TDLP errata section and point out that the
example code needs to be fixed to allow for this possibility.

Thanks for considering adding to the errata. Which particular example on
page 143 fails?

Andrei
```
May 12 2011
Abid H. Mujtaba <abid.naqvi83 gmail.com> writes:
```Section 5.5 Overloading on page 142 it defines the following example
of a "find" function which searches for slices within slices:

T1[] find( T1, T2 )( T1[] longer, T2[] shorter )
if( is( typeof( longer[ 0 .. 1 ] == shorter ) : bool ) )
{
while ( longer.length >= shorter.length ) {
if ( longer[0 .. shorter.length] == shorter ) break ;
}

return longer ;
}

On page 143 it defines the following unittest :

unittest {

double[] d1 = [ 6.0, 1.5, 2.4, 3 ] ;
float[] d2 = [ 1.5, 2.4 ] ;

assert( find(d1,d2) == d1[1 .. \$] ;
}

It is the assert() that fails since the comparison longer[0 ..
shorter.length] == shorter fails because the comparison between the
double and float values fails due to bit precision and
representation issues.
```
May 12 2011
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
```On 5/12/11 11:21 AM, Abid H. Mujtaba wrote:
of a "find" function which searches for slices within slices:

T1[] find( T1, T2 )( T1[] longer, T2[] shorter )
if( is( typeof( longer[ 0 .. 1 ] == shorter ) : bool ) )
{
while ( longer.length>= shorter.length ) {
if ( longer[0 .. shorter.length] == shorter ) break ;
}

return longer ;
}

On page 143 it defines the following unittest :

unittest {

double[] d1 = [ 6.0, 1.5, 2.4, 3 ] ;
float[] d2 = [ 1.5, 2.4 ] ;

assert( find(d1,d2) == d1[1 .. \$] ;
}

It is the assert() that fails since the comparison longer[0 ..
shorter.length] == shorter fails because the comparison between the
double and float values fails due to bit precision and
representation issues.

I see. Thanks! I updated the errata with credit:

http://erdani.com/tdpl/errata

Andrei
```
May 12 2011
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
```On 5/12/11 11:00 AM, Abid H. Mujtaba wrote:
Thanks for the answer. I guess the correct technique would be to
define an "equality" function with a tolerance within 1e-08. I guess I
should head over to the TDLP errata section and point out that the
example code needs to be fixed to allow for this possibility.

Also, you may want to peruse the function approxEqual in std.math.

Andrei
```
May 12 2011
bearophile <bearophileHUGS lycos.com> writes:
```Andrei:

Also, you may want to peruse the function approxEqual in std.math.

I suggest feqrel:
http://www.digitalmars.com/d/2.0/phobos/std_math.html#feqrel

Bye,
bearophile
```
May 12 2011
Abid H. Mujtaba <abid.naqvi83 gmail.com> writes:
```The website defines the signature for feqrel to be:

int feqrel(X)(X x, X y);

It requires x and y to be the same type. But the variables we are
working with are NOT the same type. This is what started the whole
debate in the first place. I tested approxEqual and it works. Just
have to be careful with the precision one uses.
```
May 12 2011