简体   繁体   中英

Mod (%) operator on x86 vs x64

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

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?

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.

Disclaimer: I'm not a .Net programmer.

But this sounds like a bug. The operation is well defined for the inputs you supplied, and should return m_Angle . My guess is that the implementation unconditionally attempts the division m_Angle/m_2PI , which underflows for your inputs. Evidently, the handling of this condition differs between the 32-bit and 64-bit platforms. This could have been done correctly using something similar to Marcus Johansson's answer, at the cost of a slight runtime penalty for the extra range checking.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM