www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 16055] New: double.stringof is not precise

https://issues.dlang.org/show_bug.cgi?id=16055

          Issue ID: 16055
           Summary: double.stringof is not precise
           Product: D
           Version: D2
          Hardware: All
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: thomas.bockman gmail.com

The D front-end uses two fewer digits than needed for lossless conversion of
floating-point values to strings:
---
module example;

import std.conv, std.format, std.math, std.meta, std.stdio;

void main()
{
    foreach (F; AliasSeq!(real, double, float))
    {
        writeln(F.stringof);

        const allDig = cast(int)ceil(log(pow(2.0L, F.mant_dig - 1)) /
log(10.0L) + 1);
        assert(allDig == (F.dig + 2));
        writefln("\tallDig: %s", allDig);

        enum F mostDecDig = 1 + F.epsilon;
        // 16 for double: FAIL
        assert(to!F(format("%." ~ to!string(F.dig) ~ "g", mostDecDig)) !=
mostDecDig);
        // 17 for double: FAIL
        assert(to!F(format("%." ~ to!string(F.dig + 1) ~ "g", mostDecDig)) !=
mostDecDig);
        // 18 for double: PASS
        enum goodSpec = "%." ~ to!string(F.dig + 2) ~ "g";
        static if (!is(F == real)) // to!real(string) is not precise!
            assert(to!F(format(goodSpec, mostDecDig)) == mostDecDig);

        // This is a very subtle issue; even the D frontend gets it wrong!
        assert(mostDecDig != mixin(mostDecDig.stringof));
        writefln("\t" ~ goodSpec ~ " != %s", mostDecDig, mostDecDig.stringof);
    }
}
---
DPaste: https://dpaste.dzfl.pl/1bd14e5c3f83#line-25

--
May 21 2016