Hi,
I have programmed a discrete filter using divisions and multiplications of variables of the type long. I have tested it and all is fine.
But as long-divisions are costly and actually is done by a fixed number to the power of 2, I had the idea in optimizing the code by replacing the division by a right-shift operation.
By comparing the results differences of the two versions were detected. Add the end, I was nailing it down to one division, and could create a little test-sketch showing the unexpected behaviour.
See my code:
void setup() {
Serial.begin(115200);
delay(1000);
int m_a = 3934;
long uScal = 64000;
long m_xShift = 0;
long m_xDiv = 0;
long m_xNextShift, m_xNextDiv;
int delta;
Serial.println("n\tm_xNextShift\tm_xNextDiv\tDelta");
for(byte n = 0; n <= 5; n++) {
m_xNextShift = (((long)m_a * (m_xShift - uScal)) >> 12 ) + uScal;
m_xNextDiv = (((long)m_a * (m_xDiv - uScal)) / 4096L) + uScal;
delta = m_xNextShift - m_xNextDiv;
Serial.print(n); Serial.print("\t");
Serial.print(m_xNextShift); Serial.print("\t\t");
Serial.print(m_xNextDiv); Serial.print("\t\t");
Serial.println(delta);
m_xShift = m_xNextShift;
m_xDiv = m_xNextDiv;
}
}
void loop() {
while(1);
}
Following result is obtained (Code is running on Uno R3 using IDE 1.8.19.):
n m_xNextShift m_xNextDiv Delta
0 2531 2532 -1
1 4962 4964 -2
2 7296 7299 -3
3 9538 9542 -4
4 11692 11696 -4
5 13760 13765 -5
I have expected to be all Delta are zero, but there aren't.
Why is /4096 not the same as >>12 ? Providing deeper understanding is appreciated ![]()