Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mod (%) operator on x86 vs x64

Tags:

c#

I need help for resolve a strange bug – when I use mod (%) operator on x86 all good , But on x64 I get sometimes NaN as remainder ( it usually happens with Angle = 0). I managed to reproduce that bug outside my code , but only with Angle = double.Epsilon (at my code it also happens with Angle = 0).

class Program
{
    public const double M_PI = 3.14159265358979323846;
    static void Main(string[] args)
    {
        double m_2PI = (2 * M_PI);
        double m_Angle = double.Epsilon;
        double mod = (m_Angle % m_2PI);
        //x86 mod = 4.94065645841247E-324
        //x64 mod = NaN
        if (double.IsNaN(mod))
            Debug.Write(mod);
    }
}

Regards , Shay

like image 599
Shay Avatar asked Aug 08 '10 15:08

Shay


2 Answers

This is not a strange bug, rather a quite expected bug. If you are in the outer range of a numerical datatype and play with operations, I would be surprised if this doesn't happen.

A solution might be encapsulating the mod function.

static double myMod(double v, double m){
    if(v < m) return v; 
    return v % m;
}

Can i ask, why do you worry about such a borderline case?

like image 195
Marcus Johansson Avatar answered Oct 13 '22 17:10

Marcus Johansson


In C# the modulus operator can take more than the usual C's int values. But yeah, I guess there are differences between ISA's when you are doing epsilon quantities.

In your case the epsilon in a sufficiently small number to cause the NAN.

See if you can reproduce it with float and other types. If you could use them, the problem is "solved".

As a workaround you can do the math yourself with near epsilon and just return 0 it that case.

like image 30
Rui Avatar answered Oct 13 '22 16:10

Rui