【问题标题】:How to calculate the rate of change of a variable over time in C#?如何在 C# 中计算变量随时间的变化率?
【发布时间】:2016-12-04 17:07:46
【问题描述】:

我需要实现一个适应变量变化率的算法。假设我有一个整数 HumidityPercent 和一个外部传感器实时提供数据。 我找到了几种方法来检测我的 var 是否发生了变化:

private float HumChange 
    {
        get { return HumidityPercent; }
        set 
        {
            HumidityPercent = value;
            if (HumidityPercent != 100)
            {
                // Do what?
            }           
        }
    }

我有一个计时器(秒表)来计算经过的毫秒数。问题是:如何调用新变量中的更改来存储毫秒和新值?

 private double newHum = (HumidityPercent, timer.TotalMilliseconds);

但在那之后我该如何区分呢?

任何帮助将不胜感激。

【问题讨论】:

  • 你会如何计算像km/hr 这样的东西?你需要一个时间值和一个单位变化值
  • 我找到了几种方法来检测我的 var 是否已更改 -> 如果这就是您所需要的全部 google INotifyPropertyChanged。
  • 我有一个秒表设置,可以使用 TotalMilliSeconds

标签: c# variables rate


【解决方案1】:

如果您需要变化率,那么您需要具备三样东西:

  1. 原始值。
  2. 新值。
  3. 这些值之间的时间差。

如果您有一个计时器,那么它第一次启动时所需要做的就是储存湿度。

下次触发时,它需要将“当前”值移动到“上一个”值,更新“当前”值并计算变化率。

因此,如果您将值作为可为空的双精度值,您可以测试以查看您是否有以前的值:

private double? previous;
private double current;
private double rateOfChange;

private void TimerTick(....)
{
    if (previous == null)
    {
        current = GetHumidity();
    }
    else
    {
        previous = current;
        current = GetHumidity();
        rateOfChange = (current - previous) / time;
    }
}

【讨论】:

    【解决方案2】:

    经过彻底的搜索(以及我的大量学习),我在 @ChrisF 代码的基础上构建了一个高效而优雅的简洁片段。

        public void InitTimer()
        {
            timer = new System.Timers.Timer();
            timer.Enabled = true;
            timer.Elapsed += timer_Tick;
            timer.Interval = 200;
        }
    
        public void timer_Tick(object sender, System.Timers.ElapsedEventArgs e) 
        {
            timer.Enabled = false;
            System.Threading.Interlocked.Increment(ref current);
            if (current == 0)
            {
                current = HumidityPercent;
            }
            else
            {
                previous = current;
                current = HumidityPercent;
                RateOfChange = (current-previous)/5;
                Thread.Sleep(200);
            }
            timer.Enabled = true;
        }
    

    注意到我必须调用一次InitTimer方法,所以我使用了:

        if (firstrun == true)
        {
            InitTimer();
            firstrun = false;
        }   
    

    另外请注意,我在停止启动事件中添加了刻度,放置了一个 Thread.Sleep 并添加了非常方便和高效的 System.Threading.Interlocked.Increment(ref current)。

    感谢大家的贡献!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-16
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 2016-12-21
      相关资源
      最近更新 更多