Thread overview
Floating-point Modulus math.fmod
Nov 06, 2016
Fendercaster
Nov 07, 2016
Ilya Yaroshenko
Nov 07, 2016
Fendercaster
November 06, 2016
I'm not quite sure if this is the right forum to ask this question:
I've been trying to implement the "floating-point modulus" function from the math library. Equivalently that's what I've tried in Python too. Problem is - the results are different and not even close. Please have a look at both snippets. Maybe someone can help me out:

[code = D]
import std.math;
import std.stdio;

immutable real MODULUS = 1e8;

real floatModPow(real base, ulong exp, real mod)
{
    real r = 1.0;

    while (exp) {
        if (exp & 1) r = fmod(r * base, mod);
        exp >>= 1;
        base = fmod(base*base, mod);
    }

    return r;
}

void main()
{
    floatModPow(3.866, 987654321UL, MODULUS).writeln;
}
[/code]

In this case the result is 6.44588e+07.

[code = Python]
import math

MOD = 1e8

def fpmod(b, e, m):
    r = 1.0
    while e:
        if (e & 1):
            r = math.fmod(r * b, m)
        e >>= 1
        b = math.fmod(b * b, m)
    return r

print (fpmod(3.866, 987654321, MOD))
[/code]

In this case the result is 82031250.0.

AFAIK the D.fmod and Python.fmod functions serve the same purpose. What am I missing?
November 07, 2016
On Sunday, 6 November 2016 at 21:45:28 UTC, Fendercaster wrote:
> I'm not quite sure if this is the right forum to ask this question:
> I've been trying to implement the "floating-point modulus" function from the math library. Equivalently that's what I've tried in Python too. Problem is - the results are different and not even close. Please have a look at both snippets. Maybe someone can help me out:
>
> [...]

Python uses 64-bit doubles. You may want to try with `double` and `core.stdc.tgmath` -- Ilya
November 07, 2016
On Monday, 7 November 2016 at 09:21:11 UTC, Ilya Yaroshenko wrote:
> On Sunday, 6 November 2016 at 21:45:28 UTC, Fendercaster wrote:
>> I'm not quite sure if this is the right forum to ask this question:
>> I've been trying to implement the "floating-point modulus" function from the math library. Equivalently that's what I've tried in Python too. Problem is - the results are different and not even close. Please have a look at both snippets. Maybe someone can help me out:
>>
>> [...]
>
> Python uses 64-bit doubles. You may want to try with `double` and `core.stdc.tgmath` -- Ilya

I'll give it a shot. Since the "real" type usually considers 80-bit operands, is the D variant more precise? And which of those two results is correct, if any?