Difference between revisions of "Floating Point Gotchas"

From D Wiki
Jump to: navigation, search
(Created page with "see forum discussion here: http://forum.dlang.org/post/oxadmevgkefklttnbbpi@forum.dlang.org Floating point comparisons should be undertaken with care, because decimal numbers...")
 
m (fix formatting)
Line 12: Line 12:
  
  
void main() @safe {
+
    void main() @safe {
    import std.stdio, std.range, std.algorithm, std.math;
+
        import std.stdio, std.range, std.algorithm, std.math;
 
+
   
    immutable float oneDegree = (PI / 180.0f);
+
        immutable float oneDegree = (PI / 180.0f);
    immutable float first = -(oneDegree * 10.0f);
+
        immutable float first = -(oneDegree * 10.0f);
    immutable float second = (oneDegree * 10.0f);
+
        immutable float second = (oneDegree * 10.0f);
    immutable float step = 0.000001f;
+
        immutable float step = 0.000001f;
    immutable float[] r = iota(first, second, step).array;
+
        immutable float[] r = iota(first, second, step).array;
 
+
   
    //r.writeln;
+
        //r.writeln;
 
+
   
    immutable float item = 0.174531f;
+
        immutable float item = 0.174531f;
    r.canFind!q{ feqrel(cast()a, cast()b) >= 21 }(item).writeln;
+
        r.canFind!q{ feqrel(cast()a, cast()b) >= 21 }(item).writeln;
}
+
    }

Revision as of 16:49, 26 February 2015

see forum discussion here: http://forum.dlang.org/post/oxadmevgkefklttnbbpi@forum.dlang.org

Floating point comparisons should be undertaken with care, because decimal numbers cannot be exactly represented using float or double. The classic reference on this topic is here:

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html


One should therefore in most cases use std.math.feqrel and or std.math.approxEqual instead of checking for simple equality.

These functions may be passed as a predicate to the std.algorithm library in Phobos when for example doing a search for a specific floating point value:


   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;
   }