Accuracy of floating point calculations

kinke noone at nowhere.com
Tue Oct 29 20:15:13 UTC 2019


On Tuesday, 29 October 2019 at 16:20:21 UTC, Daniel Kozak wrote:
> On Tue, Oct 29, 2019 at 5:09 PM Daniel Kozak 
> <kozzi11 at gmail.com> wrote:
>>
>> On Tue, Oct 29, 2019 at 4:45 PM Twilight via 
>> Digitalmars-d-learn <digitalmars-d-learn at puremagic.com> wrote:
>> >
>> > D calculation:
>> >mport std.stdio;
> import std.math : pow;
> import core.stdc.math;
>
> void main()
> {
>      writefln("%12.3F",log(1-0.9999)/log(1-(1-0.6)^^20));
> }
>> >    writefln("%12.2F",log(1-0.9999)/log(1-(1-0.6)^^20));
>> >
>> > 837675572.38
>> >
>> > C++ calculation:
>> >
>> >    cout<<setprecision(12)<< 
>> > (log(1-0.9999)/log(1-pow(1-0.6,20)))
>> > <<'\n';
>> >
>> > 837675573.587
>> >
>> > As a second data point, changing 0.9999 to 0.75 yields
>> > 126082736.96 (Dlang) vs 126082737.142 (C++).
>> >
>> > The discrepancy stood out as I was ultimately taking the 
>> > ceil of the results and noticed an off by one anomaly. 
>> > Testing with octave, www.desmos.com/scientific, and 
>> > libreoffice(calc) gave results consistent with the C++ 
>> > result. Is the dlang calculation within the error bound of 
>> > what double precision should yield?
>>
>> If you use gdc or ldc you will get same results as c++, or you 
>> can use C log directly:
>>
>> import std.stdio;
>> import std.math : pow;
>> import core.stdc.math;
>>
>> void main()
>> {
>>      writefln("%12.3F",log(1-0.9999)/log(1-(1-0.6)^^20));
>> }
>
> My fault, for ldc and gdc you will get same result as C++ only 
> when you use pow not ^^(operator) and use doubles:
>
> import std.stdio;
> import std.math;
>
> void main()
> {
>      writefln("%12.3F",log(1-0.9999)/log((1-pow(1-0.6,20))));
> }

The real issue here IMO is that there's still only a `real` 
version of std.math.log. If there were proper double and float 
overloads, like for other std.math functions, the OP would get 
the expected result with his double inputs, and we wouldn't be 
having this discussion.

For LDC, it would only mean uncommenting 2 one-liners forwarding 
to the LLVM intrinsic; they're commented because otherwise you'd 
get different results with LDC compared to DMD, and other forum 
threads/bugzillas/GitHub issues would pop up.

Note that there's at least one bugzilla for these float/double 
math overloads already. For a start, one could simply wrap the 
corresponding C functions.


More information about the Digitalmars-d-learn mailing list