Dear Forum,
I have experienced some strange behaviour using float/double values in a formula calculation.
Using the same static double values the result may differ each time I run the calculation?
I'm using a LPC824 (Cortex M0) with no FPU and KEIL-MDK. No MicroLIB and default compiler version 5
I'm aware of the usage of double/float precision issue. But this problem is when using the same values, the result is different each time I run a calculation.
I have a voltage (double) from a ADC, that is run through a formula, that uses 7 coefs (double).
The formula is this:
dResult = V0[paramIndex] + ( (dTemp-T0[paramIndex])*(P1[paramIndex]+(dTemp-T0[paramIndex])*(P2[paramIndex]+(dTemp-T0[paramIndex])*(P3[paramIndex]+P4[paramIndex]*(dTemp-T0[paramIndex]))))/( 1+(dTemp-T0[paramIndex])*(q1[paramIndex]+q2[paramIndex]*(dTemp-T0[paramIndex]))));
V0[], T0[], P1[], P2[], P3[], P4[], q1[] and q2[] contains static double values. So they do neve change.
dTemp is the double value (voltage) passed to the function containing the formula.
If I also keep the dTemp stable (fixed static value of 27.8125) the dResult is different each time I run the formula. If I use the value of 27.7812 it is the same value each time.
Why do I see this behavior? Why is the result not the same each time?
Thomas
Hi,
Sorry about the missed tag. The complete code is seen below (Hopefully with the correct tags)
// Defined calculation values #define cjT0t 2.5000000E+1 #define cjV0t 9.9198279E-01 #define cjP1t 4.0716564E-02 #define cjP2t 7.1170297E-04 #define cjP3t 6.8782631E-07 #define cjP4t 4.3295061E-11 #define cjq1t 1.6458102E-02 #define cjq2t 0.0000000E+00 // array with data double T0[4] = {0, 0, 0, cjT0t}; double V0[4] = {0, 0, 0, cjV0t}; double P1[4] = {0, 0, 0, cjP1t}; double P2[4] = {0, 0, 0, cjP2t}; double P3[4] = {0, 0, 0, cjP3t}; double P4[4] = {0, 0, 0, cjP4t}; double q1[4] = {0, 0, 0, cjq1t}; double q2[4] = {0, 0, 0, cjq2t}; double q3[4] = {0, 0, 0, cjq2t}; double Calculation(double dTemp, byte paramIndex) { dTempT0 = 0.0; dq1q2Temp = 0.0; dMulti = 0.0; dDivider = 0.0; // Broken up formula for the divider dTempT0 = dTemp-T0[paramIndex]; dq1q2Temp = q1[paramIndex]+q2[paramIndex]*(dTempT0); dMulti = dTempT0*dq1q2Temp; dDivider = 1.0+dMulti; // Broken up formula dCalc1 = P4[paramIndex]*(dTempT0); dCalc2 = (P3[paramIndex]+ P4[paramIndex]*(dTempT0)); dCalc3 = (dTempT0)*((P3[paramIndex]+ P4[paramIndex]*(dTempT0))); dCalc4 = P2[paramIndex]+(dTempT0)*((P3[paramIndex]+ P4[paramIndex]*(dTempT0))); dCalc5 = (dTempT0)*(P2[paramIndex]+(dTempT0)*((P3[paramIndex]+ P4[paramIndex]* (dTempT0)))); dCalc6 = P1[paramIndex]+dCalc5; dCalc7 = (dTempT0)*(P1[paramIndex]+dCalc5); // Result with pre calculated divider dResult = V0[paramIndex] + ( (dTempT0)*(P1[paramIndex]+(dTempT0)*(P2[paramIndex]+ (dTempT0)*(P3[paramIndex]+P4[paramIndex]*(dTempT0))))/(dDivider)); // Result with all formula part pre calculated dResult1 = V0[paramIndex] + ( dCalc7/(dDivider)); // Result with formula directly calculated dResult2 = V0[paramIndex] + ( (dTemp-T0[paramIndex])*(P1[paramIndex]+(dTemp- T0[paramIndex])*(P2[paramIndex]+(dTemp-T0[paramIndex])* (P3[paramIndex]+P4[paramIndex]*(dTemp-T0[paramIndex]))))/( 1+(dTemp- T0[paramIndex])*(q1[paramIndex]+q2[paramIndex]*(dTemp-T0[paramIndex])))); // Return the result here return dResult; } // Data for calculation test double fCJTemps[] = {27.7812, 27.7812, 27.7812, 27.7812, 27.7812, 27.7812, 27.7812, 27.7812, 27.8125, 27.8125, 27.8125, 27.8125, 27.8125, 27.8125, 27.8125, 27.8125}; int nCount = 16; int nIndex = 0; // Main loop int main(void) { // Init stuff while(1) { if(nIndex >= nCount) { nIndex = 0; } double dCalculation = Calculation(fCJTemps[nIndex], 3); nIndex++; } }
.