そこで、いくつかの便利なメソッドを使用して、角度の値を表す独自の構造体を作成しました。ただし、デバッグ モードでは機能しますが、リリース モードで最適化をオンにすると、コードの動作が異なります。何か不足していますか?ジッターすると何か変わるの?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);