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.
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++; } }
.