Using this code:
import std.conv, std.stdio;
void main() {
auto s = "2.9";
auto n = s.to!(float);
auto n2 = s.to!(double);
auto n3 = s.to!(real);
[n == 2.9, n2 == 2.9, n3 == 2.9].writeln;
}
I get this result:
[false, false, false]
Huh? If a literal 2.9
is not a float
, double
or real
, what is it?
At run.dlang.io, I'm seeing [false, true, true]
.
This may give you a hint as to why you're getting the results you see:
writefln("%a", n);
writefln("%a", n2);
writefln("%a", n3);
writefln("%a", 2.9);
Due to how floating point values are stored, you can't rely on ==
when you've done any sort of transformation on them. In this case, since the values are parsed from a string, you aren't seeing the precise bit pattern that matches the literal 2.9
. Contrast that with the below code, which should result in an array of true
values:
auto n = 2.9;
auto n2 = 2.9;
auto n3 = 2.9;
[n == 2.9, n2 == 2.9, n3 == 2.9].writeln;
So in your case, you probably should use std.math.approxEqual:
[approxEqual(n, 2.9), approxEqual(n2, 2.9), approxEqual(n3, 2.9)].writeln;
I also recommend Don Clugston's DConf 2016 talk, Using Floating Point Without Losing Your Sanity.