We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
My function calculates scalar value from dB value using formular scalar = 10 ^ (dB / 20)
In case of ARMCLANG V6.12 and Optimizer Level -O2 the calculation fails as it is shown in my test code.
Maybe, I overlook something, do I?
#include "stm32f4xx.h" #include <stdio.h> #include <stdint.h> #include <math.h> static volatile int8_t dB; static int8_t lastGain; /**/ void setGain(int8_t gain) { float vol; if (lastGain == gain) { // value is already set return; } // calculate scalar value vol = powf(10.f, (float)gain / 20.f); // = 0.199526... // check limits if (vol > 10) { // "vol out of range" is printed in case of ARMCLANG V6.12 and Optimization > -O2 printf("vol out of range\n"); } else { // "passed" is printed in case of ARMCLANG V6.12 and Optimization -O0 or -O1 printf("passed\n"); lastGain = gain; } } /**/ int main(void) { dB = -14; for(;;) { setGain(dB); } }
"gain" value is 0xFFFFFFF2 (-14) on function setGain entry which is correct.
Actually, if that were the case, it would not be correct. The value of "gain" cannot be that --- because that value is way too large to fit into the int8_t type.
Now, the CPU register holding the value may contain all those bytes, but only one of those can be "gain" itself.
The actual problem then would be a failure to sign-extend this single byte before passing it to a compiler intrinsic function that expects to be fed a 32-bit value.