Q:

Float doesn't increase after X number

I have a float for totalPoints which is being automatically increased by the Timer, but after totalPoints reaches certain number, it doesn't seem to increase no more. I did not put any limits so I'm not sure why is it happening.
So, totalPoints stops increasing when it reaches "2097152" value.
Here's part of my code:
public float totalPoins;

void AccumulatePoints()
{

   timer += Time.deltaTime * miningPowerValue;

   if (timer > 1f)
   {    
      totalPoints += someValue;
      timer = 0;    
   }
}

So basically it accumulates points depending on miningPowerValue. If its low, it will accumulate on a slower rate, higher - faster. Please help. I'm confused.

A:

Floating-point numbers get less precise as they get bigger. You've ran into a case where they're big enough that the amount you're trying to add is smaller than the smallest possible difference between numbers of that size. Switch to double or something else with more precision.

A:

To expand on Joseph Sible's answer in a way that I can't simply through a comment.
A single-precision floating-point value is a method of specifying a floating-point value, and in most programming languages is defined by the specification of IEEE 754. We can assume that C#'s floating-point values conform to IEEE 754. Floating point values are given a certain amount of bytes, which they use in three chunks: The sign (positive or negative), the exponent ('y' in x * 10^y), and the value ('x' in x * 10^y). (Note: The definition of these three chunks is a little more elaborate than stated here, but for this example, it suffices).
In other words, a floating point value would encode the value "2,000.00" as "positive, 3, 2". That is, positive 2 * 10^3, or 2 * 1000, or 2,000.
This means that a floating point value can represent a very large value, but it also means that very large values tend to encounter errors. At a certain point, floats need to start "lopping off" the end of their information, in order to get the best approximation for the space they have.
For example, assume we were trying to use a very small version of a floating point value to define the value 1,234,567, and it only has the space for 4 digits in its x. 1,234,567 would become "positive, 6, 1.234"; 1.234 + 10 ^ 6, which calculates to 1.234 * 1,000,000, which calculates to 1,234,000 - the last three digits are removed, because they are the "least significant" for the purposes of estimation. Assume we store this value to the variable Foo.
Now, say you try to add 1 to this value, via Foo += 1. The value would become 1,234,001. But since our floating-point value can only store the 4 largest digits, that 1 gets ignored. 1,234,000 is a good enough approximation for 1,234,001. Even if you added 1 a thousand times, it wouldn't change anything because it gets rounded off every time you add. Meanwhile, adding 1,000 directly would, in fact, have an effect.
This is what is happening in your code, on a much larger scale, and what Joseph Sible was trying to convey. This also explains why totalPoints += 0.5f will work when 0.1136f wont - 0.5 is a larger number than 0.1136, which means that 0.1136 stops being "significant" before 0.5 does. He recommended you use double, which is more precise. A double-precision floating-point value is similar to a single-precision floating point value, but considerably larger; that is, a double can store more bits than a float (about twice as many, in fact), so smaller numbers won't be lost as easily. This would solve your problem, at least up until the point where double needs to start lopping off small numbers again!

A:

The problem is that you are exceeding the precision of a `float' which is only 7 digits.
Look at the following simple code:
void Main()
{
    float f = 0.0f;
    float i = 0.1136f;

    int j = 0;
    while (f <= 3000000.0f)  //I arbitrarily chose 3 million here for illustration
    {
        f += i;

        //Only print after every 1000th iteration of the loop
        if (j % 1000 == 0)
        {
            Console.WriteLine(f);   
        }

        j++;
    }
}

At the beginning of this code you will see values like the following:
0.1136
113.7148
227.3164
340.9067
454.4931
568.0796

Then, after a bit, the decimal portion starts shrinking as the whole number portion grows:
9430.525
9543.807
9657.088
9770.369
9883.65
9996.932
10110.21
10223.49
10336.78
10450.06
10563.34

But as the value gets higher and higher, it eventually just outputs this:
999657.9
999782.9
999907.9
1000033
1000158
1000283
1000408
1000533
1000658
1000783

Notice how the part after decimal shrinks but the part before it increases?  Since the float data type only has 7 digits of precision, the least significant digits after the decimal point are chopped off.  double on the other hand has 16 digits of precision. 
I hope this helps to explain what is happening.

