From 1cbab7faa48c897c3d7db23b3576e31668da746b Mon Sep 17 00:00:00 2001 From: Edgar Bonet Date: Tue, 13 Feb 2018 23:12:36 +0100 Subject: [PATCH 1/2] Avoid undefined behavior on integer overflow Arithmetic overflow on signed integral types is undefined behavior in C++. In contrast, unsigned types overflow in a well defined manner, modulo MAX(type)+1, which is the right thing when computing differences of timestamps returned by `micros()'. Fixes #3. --- FilterDerivative.cpp | 2 +- FilterDerivative.h | 2 +- FilterOnePole.cpp | 2 +- FilterOnePole.h | 2 +- FilterTwoPole.cpp | 2 +- FilterTwoPole.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/FilterDerivative.cpp b/FilterDerivative.cpp index 6446267..5e101bf 100644 --- a/FilterDerivative.cpp +++ b/FilterDerivative.cpp @@ -2,7 +2,7 @@ #include "Arduino.h" float FilterDerivative::input( float inVal ) { - long thisUS = micros(); + unsigned long thisUS = micros(); float dt = 1e-6*float(thisUS - LastUS); // cast to float here, for math LastUS = thisUS; // update this now diff --git a/FilterDerivative.h b/FilterDerivative.h index 30aa2f1..c49cc96 100644 --- a/FilterDerivative.h +++ b/FilterDerivative.h @@ -3,7 +3,7 @@ // returns the derivative struct FilterDerivative { - long LastUS; + unsigned long LastUS; float LastInput; float Derivative; diff --git a/FilterOnePole.cpp b/FilterOnePole.cpp index 8c42eb7..7dae08f 100644 --- a/FilterOnePole.cpp +++ b/FilterOnePole.cpp @@ -17,7 +17,7 @@ void FilterOnePole::setFilter( FILTER_TYPE ft, float fc, float initialValue ) { } float FilterOnePole::input( float inVal ) { - long time = micros(); + unsigned long time = micros(); ElapsedUS = float(time - LastUS); // cast to float here, for math LastUS = time; // update this now diff --git a/FilterOnePole.h b/FilterOnePole.h index 8035759..ad78b04 100755 --- a/FilterOnePole.h +++ b/FilterOnePole.h @@ -29,7 +29,7 @@ struct FilterOnePole { // 35 mins, 47 seconds ... however, the wrap does not matter, // because the delta will still be correct (always positive and small) float ElapsedUS; // time since last update - long LastUS; // last time measured + unsigned long LastUS; // last time measured FilterOnePole( FILTER_TYPE ft=LOWPASS, float fc=1.0, float initialValue=0 ); diff --git a/FilterTwoPole.cpp b/FilterTwoPole.cpp index 7a8c6fa..3d1ed1d 100755 --- a/FilterTwoPole.cpp +++ b/FilterTwoPole.cpp @@ -120,7 +120,7 @@ void FilterTwoPole::setAsFilter( OSCILLATOR_TYPE ft, float frequency3db, float i float FilterTwoPole::input( float drive ) { Fprev = drive; // needed when using filter as a highpass - long now = micros(); // get current time + unsigned long now = micros(); // get current time float dt = 1e-6*float(now - LastTimeUS); // find dt LastTimeUS = now; // save the last time diff --git a/FilterTwoPole.h b/FilterTwoPole.h index 9b63f1c..4d0384e 100755 --- a/FilterTwoPole.h +++ b/FilterTwoPole.h @@ -41,7 +41,7 @@ struct FilterTwoPole { bool IsHighpass; // false for normal output, true will make a lowpass into a highpass - long LastTimeUS; // last time measured + unsigned long LastTimeUS; // last time measured FilterTwoPole( float frequency0 = 1, float qualityFactor = 1, float xInit = 0); From 905b702fe05083e35013cc5e2cab9ee0a59e9fbe Mon Sep 17 00:00:00 2001 From: Edgar Bonet Date: Wed, 14 Feb 2018 16:58:21 +0100 Subject: [PATCH 2/2] Keep comments consistent with the code --- FilterOnePole.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FilterOnePole.h b/FilterOnePole.h index ad78b04..c0ab393 100755 --- a/FilterOnePole.h +++ b/FilterOnePole.h @@ -25,8 +25,8 @@ struct FilterOnePole { float X; // most recent input value - // elapsed times are kept in long, and will wrap every - // 35 mins, 47 seconds ... however, the wrap does not matter, + // elapsed times are kept in unsigned long, and will wrap every + // 71 mins, 35 seconds ... however, the wrap does not matter, // because the delta will still be correct (always positive and small) float ElapsedUS; // time since last update unsigned long LastUS; // last time measured