循环中的值比较,当值相等时断开循环的最佳方法?

时间:2013-01-29 13:40:34

标签: c# multithreading algorithm loops

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

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

海拔变化有两个属性; Altitude和RateOfClimb:

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,你仍然无法100%确定这两个值是否相等。

5 个答案:

答案 0 :(得分: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)
}

答案 1 :(得分: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);
}

答案 2 :(得分:1)

    public bool AlttudeReached(double alt1, double alt2, double rateofClimb) {
        return rateofClimb > 0 ? alt1 >= alt2 : alt2 >= alt1;
    }

答案 3 :(得分: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
}

答案 4 :(得分:0)

浮点数/双打的问题是检查平等很难。因此,你应该使用&#39;范围&#39;你认为他们等于&#34;。

在一行中上下覆盖:

while(Math.Abs(Altitude - AltitudeChange.Altitude) > 0.0001)