0

I try to convert two byte to float and I have problem with precision. In my case I read temp and store into two bytes. For example 14.69*C - 14(dec) to one byte and 69(dec) to second byte. Then I would like to convert this bytes to float and compare with another float, for example:

byte byte1 = 0xE;
byte byte2 = 0x45;

float temp1 = (float) byte1*1.0 + (float) byte2*0.01; // byte2*0.1 if byte2<10
float temp2 = 14.69;
...
if (temp1==temp2){
  ...
}

I expected temp1 value 14.69 but value is 14.68999958 - Why, and what is the solution?

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • 1
    To understand what's going on you really need to read this: https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf – shuttle87 Nov 12 '15 at 21:12
  • FAQ. Try searching for "compare float values". **Never** test for their equality especially if the values are assigned by different methods: the stored values are not necessarily accurate. `0.01` cannot be accurately represented in the `float` format. – Weather Vane Nov 12 '15 at 21:14
  • Also, be aware that `0.01` is of type `double`, it's then re-interpreted as `float` leading to more loss of precision. – Weather Vane Nov 12 '15 at 21:19
  • Read [What Every Programmer Should Know About Floating-Point Arithmetic](http://floating-point-gui.de/) – Gilles 'SO- stop being evil' Nov 12 '15 at 22:35
  • 1/ The comment in your code implies that you intend to represent 14.1 as byte1 = 14, byte2 = 1. How are you going to represent 14.01 ? – Pascal Cuoq Nov 13 '15 at 00:49
  • 2/ Yes, “14.68999958” is the decimal approximation closest to the `float` that gets contained in `temp2` after `float temp2 = 14.69;`. If `temp1` contains that value too, the two are equal. – Pascal Cuoq Nov 13 '15 at 00:56

2 Answers2

0

Every time a floating point operation is done, some precision is lost. You can try to reduce the error by replacing floating point arithmetic with int as much as possible. For example:

((float)((unsigned int)byte1 * 100 + (unsigned int)byte2))/100.0

also, comparing floats for strict equality can fail due to machine precision issues, you should use if (fabsf(f1 - f2) < EPSILON)

Sasha Pachev
  • 5,162
  • 3
  • 20
  • 20
0

I think you should use the bytes as they are before converting them in float, float are not really precise when it comes to equality.