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;
}
}
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);