所以我用一些方便的方法制作了自己的结构来表示角度值。但是,虽然它在调试模式下工作,但在发布模式下打开优化时,我的代码表现不同。我错过了什么吗?当它被jited时有什么变化吗?这是 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
。
另外,如果我取消注释“ WriteLine
NormalizeRotation”,它会按预期工作。
编辑:忘了提,它作为插件在另一个应用程序中运行,它通过 COM 与之通信。
Edit2:如果我通过 Visual Studio 启动它,或者如果我在启动它后立即附加到进程(而不是我必须在一段时间后附加到它),它似乎不会发生。
Edit3:似乎这避免了这个问题,出于某种原因......只是运气,还是因为它不使用隐式转换?
var periodValue = period.Value;
var newAngle = (iAngle)((Value % periodValue + periodValue) % periodValue);