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 conversion 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 snippet 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);