Search code examples
cembeddedblackfin

Converting fractions to floating point


I'm trying to convert a fraction to floating point and use it for comparison. but the values are too small and it returns true for the results of the Boolean variables. is my converision correct ? or should I do it in another way which I don't know ?

A test case:

  // result is -0.0074
  float coilh0re = fr32_to_float(GO_coil_H[0].re)*0.8f;
  // result is -0.0092
  float coilrefundamental = fr32_to_float(CoilEepromData.coilboardhspule.reFundamental);
  // result is -0.01123
  float coilh0re2 = fr32_to_float(GO_coil_H[0].re)*1.2f;
  -0.0074>-0.0092> -0.01123

here is a snipped of the code

       bool resultA  = fr32_to_float(GO_coil_H[0].re)*0.8f < fr32_to_float(CoilEepromData.coilboardhspule.reFundamental)  ? 1 : 0;
       bool resultB  = fr32_to_float(CoilEepromData.coilboardhspule.reFundamental)  <= fr32_to_float(GO_coil_H[0].re)*1.2f ? 1 : 0;

       bool resultAB = !(resultA & resultB); // always true

       bool resultC  =  fr32_to_float(GO_coil_H[1].re)*0.8f < fr32_to_float(CoilEepromData.coilboardhspule.reHarmonic) ? 1:0;
       bool resultD  = fr32_to_float(CoilEepromData.coilboardhspule.reHarmonic)  <= fr32_to_float(GO_coil_H[1].re)*1.2f ? 1:0;

       bool resultCD = !(resultC & resultD); // always true

       bool resultE  =  fr32_to_float(GO_coil_H[0].im)*0.8f < fr32_to_float(CoilEepromData.coilboardhspule.imFundamental)? 1 : 0;
       bool resultF  =  fr32_to_float(CoilEepromData.coilboardhspule.imFundamental) <= fr32_to_float(GO_coil_H[0].im)*1.2f ? 1 : 0;

       bool resultEF = !(resultE & resultF);// always true

       bool resultG  =  fr32_to_float(GO_coil_H[1].im)*0.8f < CoilEepromData.coilboardhspule.imHarmonic ? 1 : 0;
       bool resultH  =  fr32_to_float(CoilEepromData.coilboardhspule.imHarmonic) <= fr32_to_float(GO_coil_H[1].im)*1.2f ? 1 : 0;

       bool resultGH = !(resultG & resultH);// always true

        if(! ((fr32_to_float(GO_coil_H[0].re)*0.8f < fr32_to_float(CoilEepromData.coilboardhspule.reFundamental)) && (fr32_to_float(CoilEepromData.coilboardhspule.reFundamental) <= fr32_to_float(GO_coil_H[0].re)*1.2f) ) 
        || ! ((fr32_to_float(GO_coil_H[1].re)*0.8f < fr32_to_float(CoilEepromData.coilboardhspule.reHarmonic))    && (fr32_to_float(CoilEepromData.coilboardhspule.reHarmonic) <= fr32_to_float(GO_coil_H[1].re)*1.2f)    )
        || ! ((fr32_to_float(GO_coil_H[0].im)*0.8f < fr32_to_float(CoilEepromData.coilboardhspule.imFundamental)) && (fr32_to_float(CoilEepromData.coilboardhspule.imFundamental) <= fr32_to_float(GO_coil_H[0].im)*1.2f) )
        || ! ((fr32_to_float(GO_coil_H[1].im)*0.8f < fr32_to_float(CoilEepromData.coilboardhspule.imHarmonic))    && (fr32_to_float(CoilEepromData.coilboardhspule.imHarmonic) <= fr32_to_float(GO_coil_H[1].im)*1.2f)    ) )

        {
            eUserCode           = E_USER_SOIL_FAILED;
            eProcessState       = E_ERROR_HANDLING;  
        }

}

Solution

  • If appears OP wants to test if a value reFundamental is in range +/-20% of re. This is not a float precision issue, but a math one.

    // Simplified problem
    float re = -0.01123f/1.2f;
    float reFundamental = -0.0092f;
    bool resultA  = re*0.8f < reFundamental;
    bool resultB  = reFundamental <= re*1.2f;
    bool resultAB = !(resultA & resultB); // always true
    

    But the values are negative and so the < and <= should be reversed.

    Various alternatives. Example: (Adjust to taste)

    bool in_range(float x, float limit, float factor) {
      float limitp = limit*(1.0f + factor);
      float limitm = limit*(1.0f - factor);
    
      if (x > limitm) return x <= limitp;
      if (x < limitm) return x >= limitp;
      return x == limitp;
    }
    
    bool resultAB = !in_range(fr32_to_float(CoilEepromData.coilboardhspule.reFundamental),   
        fr32_to_float(GO_coil_H[0].re), 0.20);