1

2 つのプロパティを持つ架空の Aircraft クラスを考えてみましょう。高度と高度変化:

public class Aircraft  
{
    public double Altitude { get; set; }
    public AltitudeChange { get; set; }
}

高度の変化には 2 つのプロパティがあります。高度と上昇率:

public class AltitudeChange
{ 
    public double Altitude { get; set; }
    public double RateOfClimb { get; set; } //Negative for descent
}

経過時間と上昇率に基づいて航空機の高度を更新する「ワーカー スレッド」がある場合、新しい高度に達したときにループが確実に停止するようにするための理想的な設計/実装は何ですか?

private void AltitudeThreadWork()
{
    var updated = DateTime.Now;

    while (Aircraft.Altitude != AltitudeChange.Altitude)
    {
        UpdateAltitude((DateTime.Now - updated).TotalMilliseconds);
        updated = DateTime.Now;
        Thread.Sleep(40);
    }
}

private void UpdateAltitude(double ellapsed)
{
    Aircraft.Altitude += ellapsed*(AltitudeChange.RateOfClimb/60000d);
}

たとえば、倍精度数が互いに正確に等しくならないことが多いため、このスレッドは上昇プロセスを停止しません。

double を int にキャストしても、2 つの値が等しいことを 100% 保証することはできません。

4

5 に答える 5

2

記号の変化を探すことでそれを行うことができます:

private void AltitudeThreadWork()
{
    bool isOrigPositive = Aircraft.Altitude - AltitudeChange.Altitude > 0;

    do
    {
        var updated = DateTime.Now;
        UpdateAltitude((DateTime.Now - updated).TotalMilliseconds);
        Thread.Sleep(40);
        bool isNowPositive = Aircraft.Altitude - AltitudeChange.Altitude > 0;
    } 
    while (isOrigPositive == isNowPositive)
}
于 2013-01-29T13:49:30.117 に答える
1
    public bool AlttudeReached(double alt1, double alt2, double rateofClimb) {
        return rateofClimb > 0 ? alt1 >= alt2 : alt2 >= alt1;
    }
于 2013-01-29T13:47:34.890 に答える
1

基本的に、オーバーシュートしないようにする必要があります。したがって、等しいかどうかを確認する代わりに、変更を適用すると目標高度からさらに遠ざかるか、近づくかを確認してください。

また、高度を調整してオーバーシュートを停止するスレッドを変更することもできます。たとえば、擬似コードは次のとおりです。

double potentialAltitude = currentAltitude + AltitudeChange;
if (AltitudeChange < 0) // Going down... don't go below the "floor"
{
    newAltitude = Math.Max(potentialAltitude, TargetAltitude);
}
else // Going up... don't go above the "ceiling"
{
    newAltitude = Math.Min(potentialAltitude, TargetAltitude);
}
于 2013-01-29T13:45:44.597 に答える
0
private void AltitudeThreadWork()
{
    var updated = DateTime.Now;

    bool above = Aircraft.Altitude > AltitudeChange.Altitude;  // Determine if it is a climbing or a descent

    while ((Aircraft.Altitude > AltitudeChange.Altitude) == above)  // Check if it is in the same side of the plane defined by Altitude 
    // (because altitude is a continuous function, if it is on the other "side" it means it has crossed the given altitude)
    {
        UpdateAltitude((DateTime.Now - updated).TotalMilliseconds);
        updated = DateTime.Now;
        Thread.Sleep(40);
    }

    Aircraft.Altitude = AltitudeChange.Altitude;  // Altitude is reached
}
于 2013-01-29T13:45:55.657 に答える
0

float/double の問題は、等しいかどうかのチェックが難しいことです。したがって、それらを「等しい」と見なす「範囲」を使用する必要があります。

1行で上下をカバー:

while(Math.Abs(Altitude - AltitudeChange.Altitude) > 0.0001)
于 2013-01-29T13:46:37.920 に答える