2
#include<stdio.h>

int main()
{

    int loopCounter = 0;    
    float data1,data2;

    data1 = 2000.0f;
    data2 = 0.0001f;

    while(1)
    {               
      data1 = data1 + data2;
      printf("Loop Counter %d , Data %f\n",loopCounter,data1);
      loopCounter++;
    }
    return 0;
}

I am running this code on Linux machine using the GCC compiler but if the addition of the 2 float reaches the value 2048.0 it does not change anymore.

Does anyone have an idea why this is happening?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 5
    What do you mean with "halt"? Does it stop or does it continue to print same value? – Gerhardh Aug 30 '17 at 08:52
  • 1
    Are you aware of precision limitation of floating point data types? – Gerhardh Aug 30 '17 at 08:53
  • You mean it "halts" because it adds data2 without changing data1? Are you aware of the imprecision of float? Your code is perfect to find that special value, where the data2 is so small that its affect cannot be represented in the accumulator data1. – Yunnosch Aug 30 '17 at 08:53
  • @SouravGhosh Please elaborate. Do not assume that "not changing anymore" means "not changing at all", or that "halt" means "not changing at all". The value at which changes stop occurring is likely to be higher than the init value. – Yunnosch Aug 30 '17 at 08:57
  • 1
    `2000.0001` has more precision than `float` can hold (~7 digits for IEEE-754 single precision) – phuclv Aug 30 '17 at 09:01
  • 2
    You should post the exact output of your program, not say vague things like "it halt" (what does this ever mean?) – n. m. could be an AI Aug 30 '17 at 09:03
  • halt means it continue to print same value "2048" – Avinash Dane Aug 30 '17 at 09:43
  • I have understood the root cause but can anyone tell how to avoid this in c code – Avinash Dane Aug 30 '17 at 10:34
  • @AvinashDane " how to avoid this in c code" --> Step 1: Consider 2 things: 1) With _floating point_ numbers there are about as many representable `float` in the range [1.0..2.0] and ranges [1.0e-10..2.0e-10] and [1.0e+10..2.0e+10]. 2) All `float` take a a fixed about of memory, example 32 bits. Does that make make sense to you? – chux - Reinstate Monica Aug 30 '17 at 14:54

2 Answers2

4

For any floating point value, in combination with a (much) smaller adding delta, there is a value from which adding the delta results in a value which is so "similar" to the previous one, that the representation in float is identical.

Your code is practically tailor-made to find that value.

So, while at first adding delta to 2000 and a few following values results in visible changes, your code will sooner or later (quite soon actually) reach the special value. Which I assume in your case is 2048.
2048.0 and 2048.0001 have no different representation in float. Hence the adding has no effect on the variable.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • I have understood the root cause but can anyone tell how to avoid this in c code – Avinash Dane Aug 30 '17 at 10:33
  • Cannot at all, you can only use wider floats in order to get the problem later. – Yunnosch Aug 30 '17 at 11:33
  • You can however describe what you actually wan to achieve, in a separate question, show what you have (which is bount to be more/different than this) and ask for more specific help. – Yunnosch Aug 30 '17 at 11:34
  • The application is the energy meter and I want to store the kWh accumulated value and for that I was using float as a data type. I know using double as a data type this problem will be solved. – Avinash Dane Sep 01 '17 at 09:27
2

Anyone has idea why this is happening?

Because of floating point precision.

Read Ranges of floating point datatype in C?

Notice that:

 2000.0001

already exceeds the limit a float can store (~7 digits for IEEE-754 single precision).


What happens in your case is that the precision is limited, which results in the "halting" issue you report. In other words, after some point, the adition doesn't have any actual effect (which is reflected to the user).

By that I mean that the new sum is so close to the previous sum, that their float reprecentation is the same, causing data1 to store the same value.

In your machine, this value is 2048 and all the rest additions by a small δ do not affect the float representation of data1.

gsamaras
  • 71,951
  • 46
  • 188
  • 305