## digitalmars.D - What am I doing wrong here - canFind with iota is not working

• Kingsley (10/10) Feb 26 2015 float oneDegree = (PI / 180.0);
• John Colvin (5/15) Feb 26 2015 Never check floating point numbers for equality, unless you've
• John Colvin (9/28) Feb 26 2015 This is the classic reference on the topic:
• Laeeth Isharc (8/27) Feb 26 2015 Hi John.
• bearophile (15/17) Feb 26 2015 A possible solution:
• bearophile (4/7) Feb 27 2015 With a recent Phobos bug fix you can now write:
• John Colvin (5/12) Feb 26 2015 My preference would be to find a way to construct the program
• Baz (11/21) Feb 26 2015 also mark your float litteral with the f postfix. By default FP
• Kingsley (5/30) Feb 26 2015 Adding the f still produces a false result. Also I tried changing
• Kingsley (15/49) Feb 26 2015 Hardcoding the double[] does work as expected - so why doesn't it
• Fool (11/13) Feb 26 2015 'double' represents a floating-point type with base 2.
• Baz (4/38) Feb 26 2015 Sorry, in the past i've found that similar questions about FP can
"Kingsley" <kingsley.hendrickse gmail.com> writes:
```float oneDegree = (PI / 180.0);
float first = -(oneDegree * 10.0);
float second = (oneDegree * 10.0);
float step = 0.000001;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531;
writeln(r.canFind(item));

// returns false for canFind - even though that float is in the
array ???
```
Feb 26 2015
"John Colvin" <john.loughran.colvin gmail.com> writes:
```On Thursday, 26 February 2015 at 10:55:43 UTC, Kingsley wrote:
float oneDegree = (PI / 180.0);
float first = -(oneDegree * 10.0);
float second = (oneDegree * 10.0);
float step = 0.000001;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531;
writeln(r.canFind(item));

// returns false for canFind - even though that float is in the
array ???

Never check floating point numbers for equality, unless you've
really thought about how the floating point arithmetic for this
specific problem will go. Pretty much the only place it's useful
to do is in unit tests for maths libraries.
```
Feb 26 2015
"John Colvin" <john.loughran.colvin gmail.com> writes:
```On Thursday, 26 February 2015 at 11:00:05 UTC, John Colvin wrote:
On Thursday, 26 February 2015 at 10:55:43 UTC, Kingsley wrote:
float oneDegree = (PI / 180.0);
float first = -(oneDegree * 10.0);
float second = (oneDegree * 10.0);
float step = 0.000001;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531;
writeln(r.canFind(item));

// returns false for canFind - even though that float is in
the array ???

Never check floating point numbers for equality, unless you've
really thought about how the floating point arithmetic for this
specific problem will go. Pretty much the only place it's
useful to do is in unit tests for maths libraries.

This is the classic reference on the topic:
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

but there are loads of other less rigorous explanations around
the web.

To cut a long story short: floating point maths is not the same
as maths with real numbers. It's mostly roughly the same,
sometimes catastrophically different and very, very rarely
exactly the same.
```
Feb 26 2015
"Laeeth Isharc" <Laeeth.nospam nospam-laeeth.com> writes:
```Hi John.

Tks help with ldc - will look at that shortly.

So Kingsly needs to use a predicate for canFind that returns true
if the two values being compared are close enough to being the
same given floating point quirks ?

Ie I think people diagnosed the problem, but what is the
solution...

On Thursday, 26 February 2015 at 11:00:05 UTC, John Colvin wrote:
On Thursday, 26 February 2015 at 10:55:43 UTC, Kingsley wrote:
float oneDegree = (PI / 180.0);
float first = -(oneDegree * 10.0);
float second = (oneDegree * 10.0);
float step = 0.000001;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531;
writeln(r.canFind(item));

// returns false for canFind - even though that float is in
the array ???

Never check floating point numbers for equality, unless you've
really thought about how the floating point arithmetic for this
specific problem will go. Pretty much the only place it's
useful to do is in unit tests for maths libraries.

```
Feb 26 2015
"bearophile" <bearophileHUGS lycos.com> writes:
```Laeeth Isharc:

Ie I think people diagnosed the problem, but what is the
solution...

A possible solution:

void main()  safe {
import std.stdio, std.range, std.algorithm, std.math;

immutable float oneDegree = (PI / 180.0f);
immutable float first = -(oneDegree * 10.0f);
immutable float second = (oneDegree * 10.0f);
immutable float step = 0.000001f;
immutable float[] r = iota(first, second, step).array;

//r.writeln;

immutable float item = 0.174531f;
r.canFind!q{ feqrel(cast()a, cast()b) >= 21 }(item).writeln;
}

Bye,
bearophile
```
Feb 26 2015
"bearophile" <bearophileHUGS lycos.com> writes:
```     immutable float item = 0.174531f;
r.canFind!q{ feqrel(cast()a, cast()b) >= 21 }(item).writeln;
}

With a recent Phobos bug fix you can now write:

r.canFind!q{ feqrel(a, b) >= 21 }(item).writeln;

Bye,
bearophile
```
Feb 27 2015
"John Colvin" <john.loughran.colvin gmail.com> writes:
```On Thursday, 26 February 2015 at 12:39:20 UTC, Laeeth Isharc
wrote:
Hi John.

Tks help with ldc - will look at that shortly.

So Kingsly needs to use a predicate for canFind that returns
true if the two values being compared are close enough to being
the same given floating point quirks ?

Ie I think people diagnosed the problem, but what is the
solution...

My preference would be to find a way to construct the program
such that it isn't needed.

Failing that, std.math has feqrl and approxEqual for this task.
```
Feb 26 2015
"Laeeth Isharc" <nospamlaeeth nospam.laeeth.com> writes:
```Thanks.

Rough version for Wiki here:
http://wiki.dlang.org/Floating_Point_Gotchas

It could be tidier, but I am not able to do so at moment.  Feel
free to change.

On Thursday, 26 February 2015 at 14:04:17 UTC, John Colvin wrote:
On Thursday, 26 February 2015 at 12:39:20 UTC, Laeeth Isharc
wrote:
Hi John.

Tks help with ldc - will look at that shortly.

So Kingsly needs to use a predicate for canFind that returns
true if the two values being compared are close enough to
being the same given floating point quirks ?

Ie I think people diagnosed the problem, but what is the
solution...

My preference would be to find a way to construct the program
such that it isn't needed.

Failing that, std.math has feqrl and approxEqual for this task.

```
Feb 26 2015
"Baz" <bb.temp gmx.com> writes:
```On Thursday, 26 February 2015 at 10:55:43 UTC, Kingsley wrote:
float oneDegree = (PI / 180.0);
float first = -(oneDegree * 10.0);
float second = (oneDegree * 10.0);
float step = 0.000001;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531;
writeln(r.canFind(item));

// returns false for canFind - even though that float is in the
array ???

also mark your float litteral with the f postfix. By default FP
litterals are double...IIRC

float oneDegree = (PI / 180.0f);
float first = -(oneDegree * 10.0f);
float second = (oneDegree * 10.0f);
float step = 0.000001f;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531f;
writeln(r.canFind(item));
```
Feb 26 2015
"Kingsley" <kingsley.hendrickse gmail.com> writes:
```On Thursday, 26 February 2015 at 11:04:58 UTC, Baz wrote:
On Thursday, 26 February 2015 at 10:55:43 UTC, Kingsley wrote:
float oneDegree = (PI / 180.0);
float first = -(oneDegree * 10.0);
float second = (oneDegree * 10.0);
float step = 0.000001;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531;
writeln(r.canFind(item));

// returns false for canFind - even though that float is in
the array ???

also mark your float litteral with the f postfix. By default FP
litterals are double...IIRC

float oneDegree = (PI / 180.0f);
float first = -(oneDegree * 10.0f);
float second = (oneDegree * 10.0f);
float step = 0.000001f;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531f;
writeln(r.canFind(item));

Adding the f still produces a false result. Also I tried changing
all to double but still not working - I always get false back.
Interestingly if I harcode the output of the iota into an array -
then things start to work as I expect.
```
Feb 26 2015
"Kingsley" <kingsley.hendrickse gmail.com> writes:
```On Thursday, 26 February 2015 at 11:12:42 UTC, Kingsley wrote:
On Thursday, 26 February 2015 at 11:04:58 UTC, Baz wrote:
On Thursday, 26 February 2015 at 10:55:43 UTC, Kingsley wrote:
float oneDegree = (PI / 180.0);
float first = -(oneDegree * 10.0);
float second = (oneDegree * 10.0);
float step = 0.000001;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531;
writeln(r.canFind(item));

// returns false for canFind - even though that float is in
the array ???

also mark your float litteral with the f postfix. By default
FP litterals are double...IIRC

float oneDegree = (PI / 180.0f);
float first = -(oneDegree * 10.0f);
float second = (oneDegree * 10.0f);
float step = 0.000001f;

Hardcoding the double[] does work as expected - so why doesn't it
work with the iota generated array?

double oneDegree = (PI / 180.0);
double first = -(oneDegree * 10.0);
double second = (oneDegree * 10.0);
double step = 0.000001;
double[] r = iota(first,second,step).array;

writeln(r);

double[] hardCoded = [ 0.174521, 0.174522, 0.174523, 0.174524,
0.174525, 0.174526, 0.174527, 0.174528, 0.174529, 0.17453,
0.174531, 0.174532];

double item = 0.174531;
writeln(r.canFind(item));  // false - I expect true!!!!

writeln(hardCoded.canFind(item)); // true - as I expect
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531f;
writeln(r.canFind(item));

Adding the f still produces a false result. Also I tried
changing all to double but still not working - I always get
false back. Interestingly if I harcode the output of the iota
into an array - then things start to work as I expect.

```
Feb 26 2015
"Fool" <fool dlang.org> writes:
```On Thursday, 26 February 2015 at 11:17:12 UTC, Kingsley wrote:
Hardcoding the double[] does work as expected - so why doesn't
it work with the iota generated array?

'double' represents a floating-point type with base 2.

This implies that decimal numbers like 0.1 (= 1/10 = 1/(2*5))
cannot be exactly represented using double. The double literal
0.1 refers to a number close to but not equal to the real number
0.1.

So when you use a literal step of 0.1 you actually use step
1.00000000000000005551115123126E-1.

The small error adds up in successive additions and, due to a
finite number of digits, every addition can introduce further
error.
```
Feb 26 2015
"Baz" <bb.temp gmx.com> writes:
```On Thursday, 26 February 2015 at 11:12:42 UTC, Kingsley wrote:
On Thursday, 26 February 2015 at 11:04:58 UTC, Baz wrote:
On Thursday, 26 February 2015 at 10:55:43 UTC, Kingsley wrote:
float oneDegree = (PI / 180.0);
float first = -(oneDegree * 10.0);
float second = (oneDegree * 10.0);
float step = 0.000001;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531;
writeln(r.canFind(item));

// returns false for canFind - even though that float is in
the array ???

also mark your float litteral with the f postfix. By default
FP litterals are double...IIRC

float oneDegree = (PI / 180.0f);
float first = -(oneDegree * 10.0f);
float second = (oneDegree * 10.0f);
float step = 0.000001f;
float[] r = iota(first,second,step).array;

writeln(r);

float item = 0.174531f;
writeln(r.canFind(item));

Adding the f still produces a false result. Also I tried
changing all to double but still not working - I always get
false back. Interestingly if I harcode the output of the iota
into an array - then things start to work as I expect.

Sorry, in the past i've found that similar questions about FP can
be solved by following this way. There must be something that is
not 'float' in the processing...
```
Feb 26 2015