- Home /
Comparing float value to zero
This code works as expected:
float myValue = 6.0f;
void Update()
{
myValue -= Time.deltaTime;
if(myValue < 0.0f)
myValue = 0.0f;
}
public bool IsValueZero()
{
return myValue == 0.0f;
}
But I'm curious if it's safe to use a construction like that. I'm aware of float comparsion, but also wonder - can we do a safe float to value comparsion if we are sure that our float was set to exactly that value. It don't have to be a zero, can also be something like:
float myValue = 6.43f;
if(myValue == 6.43f)
Debug.Log("It's working!");
Will this construction always work as expected?
Answer by Owen-Reynolds · Apr 02, 2015 at 02:26 PM
Yes. Setting a float directly to a value will not produce "rounding" errors. Checking if(x==4.0f)
, when you know it was directly set, is safe.
Setting a float to an int is always exactly that int (unless something like 345664345654.0, with too many significant digits.) Setting to a decimal will "round" the same both ways. So 6.43 may round to 6.42999, but it will always round the same way, so a direct compare is safe (but not commonly done.)
The only time "random" rounding occurs is when you do math. 0.1f*10 may be 1.00001. But 0.05f*20 may be 0.999999. The trick is, we know 1/3 is repeating 0.33333, so has to round. For computers, 0.1 is repeating, since it stores fractions as 1/2, 1/4, 1/8 ... . So, 0.5 won't round, and 0.5f*20 should be exactly 10 (but no one does stuff like that.)
Lerp, clamp, moveTowards, ... will give an exact number. x=lerp(2.0f, 9.0f, percent);
will give exactly 2.0 and 9.0 when percent
is less than 0 or more than 1. Because, internally, they say "if percent 1 or more, value equals 2nd number."
Thank you, that was the answer I was looking for :) Do you have any sources on the topic btw.? I assume it's a general rule in C# (and other languages probably).
The key is the 3rd para. Look up how floats are stored. 0.75 in binary is 0.11 (1/2 plus 1/4th.) Once you understand that most decimal numbers are repeating negative powers of 2 (10th is 1/16th, plus 1/64th(?) plus ... ) it should all be obvious.