c#double modulus在“Optimize Code”打开时返回0

时间:2013-05-04 14:21:25

标签: c# double jit angle modulo

所以我用自己的方法来表示角度值。但是,虽然它在调试模式下工作,但在发布模式下启用优化时,我的代码行为却不同。我错过了什么吗?当它被咬合时会有什么变化吗?这是VS2010中的.NET 3.5项目。

基本上我做了以下事情:

    Func<double, double> FromDegrees = degrees => degrees*Math.PI/180;
    double Value = FromDegrees(9);
    double period = Math.PI*2;
    double newAngle = (Value % period + period) % period;
    // newAngle is 0!

更完整的例子:

public struct Angle
{
    public readonly double Value;

    public const double AngularTolerance = 0.001; // 0.06 degrees
    public static readonly Angle FullRotation = (Angle) (Math.PI*2);

    public Angle(double angle)
    {
        Value = angle;
    }

    public static Angle FromDegree(double degrees)
    {
        return (Angle) (degrees*Math.PI/180);
    }

    public Angle NormalizeRotation(Angle? period = null)
    {
        period = period ?? FullRotation;
        var newAngle = (Angle)((Value % period + period) % period);
        //Console.WriteLine("Value=" + Value + ", Value % period="+(Value % period) + ", Value % period + period="+(Value % period + period)+", (Value % period + period) % period="+((Value % period + period) % period) + ", newAngle == period:"+(newAngle == period));

        //if (newAngle == period)
        //    newAngle = (Angle) 0;
        return newAngle;
    }

    public bool EqivalentRotation(Angle angle, Angle? period = null)
    {
        Console.WriteLine("EqivalentRotation: Value=" + Value + ", other angle=" + angle.Value);
        Console.WriteLine("EqivalentRotation2: norm(Value)=" + NormalizeRotation(period).Value + ", other norm(angle)=" + angle.NormalizeRotation(period).Value);
        return angle.NormalizeRotation(period) == NormalizeRotation(period);
    }

    public static bool operator ==(Angle a, Angle b)
    {
        return Math.Abs(a.Value - b.Value) < AngularTolerance;
    }

    public static bool operator !=(Angle a, Angle b)
    {
        return !(a == b);
    }

    public static implicit operator double(Angle length)
    {
        return length.Value;
    }

    public static explicit operator Angle(double length)
    {
        return new Angle(length);
    }
}

将EquivalentRotation称为:

Angle.FromDegree(180).EqivalentRotation(Angle.FromDegree(9))

我得到了输出

EqivalentRotation: Value=3,14159265358979, other angle=0,15707963267949
EqivalentRotation2: norm(Value)=0, other norm(angle)=0

然后返回false

另外,如果我取消注释'NormalizeRotation'中的WriteLine,它会按预期工作。

编辑:忘记提及,它在另一个应用程序中作为插件运行,通过COM进行通信。

Edit2:如果我通过Visual Studio启动它,或者如果我在启动它后立即附加到该进程(似乎我必须在一段时间后附加到它),它似乎不会发生。

Edit3:似乎这样可以避免这个问题,出于某种原因...它只是运气,还是因为它不使用隐式转换?

        var periodValue = period.Value;
        var newAngle = (iAngle)((Value % periodValue + periodValue) % periodValue);

0 个答案:

没有答案