This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Calculation with static double has different results

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

Parents
  • 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++;
     }
    }
    
    
    

    .

Reply
  • 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++;
     }
    }
    
    
    

    .

Children
No data