1

假设有两个属性的飞机类;海拔和海拔变化:

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

海拔变化有两个性质;高度和爬升率:

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);
}

例如,此线程不会停止爬升过程,因为双精度数通常不会完全相等。

即使您将双精度值转换为 int,您仍然不能 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

基本上你要确保你不会过冲。因此,与其检查是否相等,不如检查应用更改是否会使您远离目标高度或更接近目标高度。

您可能还想更改调整高度以停止超调开始的线程。例如,伪代码:

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 回答
1
    public bool AlttudeReached(double alt1, double alt2, double rateofClimb) {
        return rateofClimb > 0 ? alt1 >= alt2 : alt2 >= alt1;
    }
于 2013-01-29T13:47:34.890 回答
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

浮点数/双精度数的问题是检查相等性很困难。因此,您应该使用您认为它们“相等”的“范围”。

在 1 行中覆盖上下:

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