繁体   English   中英

x86与x64上的Mod(%)运算符

[英]Mod (%) operator on x86 vs x64

我需要帮助来解决一个奇怪的错误 - 当我在x86上使用mod(%)运算符时都很好,但是在x64上我有时会得到NaN作为余数(通常在Angle = 0时发生)。 我设法在我的代码之外重现那个bug,但只有Angle = double.Epsilon(在我的代码中它也发生在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);
    }
}

问候,谢伊

这不是一个奇怪的错误,而是一个非常期待的错误。 如果您处于数值数据类型的外部范围并使用操作,如果不发生这种情况,我会感到惊讶。

解决方案可能是封装mod函数。

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

我可以问,为什么你担心这种边缘情况?

在C#中,模数运算符可以采用比通常的C的int值更多的值。 但是,是的,我猜你在做epsilon数量时,ISA之间存在差异。

在你的情况下,epsilon的数量足够小,导致NAN。

看看你是否可以用浮动和其他类型重现它。 如果你可以使用它们,问题就“解决”了。

作为一种解决方法,您可以使用near epsilon自己进行数学计算,并在这种情况下返回0。

免责声明:我不是.Net程序员。

但这听起来像个错误。 操作已为您提供的输入定义良好,并应返回m_Angle 我的猜测是,实现无条件地尝试划分m_Angle/m_2PI ,它会为您的输入下溢。 显然,这种情况的处理在32位和64位平台之间有所不同。 这可以使用与Marcus Johansson的答案类似的方式正确完成,但需要额外的范围检查的轻微运行时间罚款。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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