# Windowsfloor() function problem

#### JimPancakes

##### Member
Please take a look at this code:

Code:
``````if keyboard_check_pressed(vk_space)
{
count_char += 0.1;

if floor(count_char) = count_char
{
image_alpha += 0.03;
}
}``````
I also made a "draw_text" of the "count_char" variable and "floor(count_char)".

The problem is that the "if floor(count_char) = count_char" function doesn't work consistently. For example when "count_char" is 1, "floor(count_char)" is 0.

But when "count_char" is 2, 3 or 4, then "floor(count_char)" works and is the same as "count_char".

But then, when "count_char" is 5, "floor(count_char)" fumbles again and stays 4.

#### nacho_chicken

##### Member
This is just a floating point math issue. You can test for yourself by running the following code:
Code:
``````// Shows a message with "0" because 0.1+0.2 is not equal to 0.3
show_message(string((0.1+0.2) == 0.3));``````
Here's a website that explains the problem you're having in-depth.
https://0.30000000000000004.com/

• JimPancakes

#### JimPancakes

##### Member
This is just a floating point math issue. You can test for yourself by running the following code:
Code:
``````// Shows a message with "0" because 0.1+0.2 is not equal to 0.3
show_message(string((0.1+0.2) == 0.3));``````
Here's a website that explains the problem you're having in-depth.
https://0.30000000000000004.com/
Is there any obvious workaround to this?
I just want to check when count_char is an integer number.

#### TsukaYuriko

##### 🌠
Forum Staff
Moderator
Use round instead of floor. That should work around the specific issue you're encountering.

• JimPancakes

#### kroart

##### Member
You can store a previous value of count_char and compare it with a current value. Something like this:
if keyboard_check_pressed(vk_space)
{
prev_count_char = count_char
count_char += 0.1;

if floor(count_char) != floor(count_char)
{
image_alpha += 0.03;
}
}

But I think a better approach will be something like this. Since you increase image_alpha every 10'th iteration:
if keyboard_check_pressed(vk_space)
{
count_char++

if (count_char == 10)
{
image_alpha += 0.03;
count_char = 0
}
}
I think this code should perform faster. And easier to read.

#### Mike

##### nobody important
GMC Elder
Why not just use an epsilon? This will give a +/- 0.01 range when comparing around "10"

if( abs(count_char-10) < 0.01 ){

}

there is also a math_set_epsilon() which may also do what you're wanting. But use this with care.....

#### kroart

##### Member
Why not just use an epsilon? This will give a +/- 0.01 range when comparing around "10"

if( abs(count_char-10) < 0.01 ){

}

there is also a math_set_epsilon() which may also do what you're wanting. But use this with care.....
So checking like "if (count_char == 10)" can fail even if increasing only with "count_char++" ?

#### TsukaYuriko

##### 🌠
Forum Staff
Moderator
Technically, any form of arithmetic operation can "fail" (read: be inaccurate), as floating points are usually not perfectly precise. The more operations you perform, the less precise things tend to get as more and more information is lost/falsified from its true intended value.

Something as simple as 4 - 4 may not equal 0 as you'd expect due to this. You just normally don't notice it because it falls under the default epsilon, gets caught by it and is still considered equivalent. Your example most likely falls under the latter category - can theoretically fail, most likely won't if you don't touch the default epsilon.

If you're curious how far off any particular result is from failing, try outputting the number via string_format with a lot of decimal digits.

#### Mike

##### nobody important
GMC Elder
++ will add one. But if it was 0.000001 to start with, then it's still "out" a little.

But if you AND the value with say \$FFFFFFFF then it'll turn the double/real into an actual INT (internally), then you'll get exact comparisons. Basically any "binary" operation, makes the variable an int64 (though I'm not so sure about HTML5 anymore. They've changed the internals quite a bit since I last saw it)

Code:
``````var r = count_char&0xffffffff;
if( r==10 ){

}``````

• TsukaYuriko

#### Alice

##### Toolmaker of Bucuresti
Forum Staff
Moderator
For this specific problem (i.e. perform some action on Xth occurrence/every X occurrences), I'd just get rid of fractions altogether and work on integers instead.
As long as integers aren't too large, they should avoid the rounding point issues altogether - and "too large" means millions for 32-bit floats while GM uses 64-bit floats internally (this may or may not vary between platforms).

So, with this in Create:
Code:
``````current_count = 0;
threshold_count = 10;``````
And this in Step:
Code:
``````if keyboard_check_pressed(vk_space)
{
current_count++;
if (current_count == threshold_count)
{
current_count = 0; // use this line if you want it every 10 keypresses, rather than on 10th keypress but not 20th or 30th etc.
image_alpha += 0.03;
}
}``````
You'll get image_alpha increase either on 10th keypress or every 10 keypresses, depending on the current_count = 0 line in the Step event.

Another alternative, when you must work with fractions (e.g. because there might be some speed-up/slow-down effect at play):
This in Create:
Code:
``````current_amount = 0;
amount_per_step = 0.1; // might vary, but generally should be a positive number
threshold_amount = 10;``````
And this in Step:
Code:
``````current_amount += amount_per_step;
while (current_amount >= threshold_amount) {
current_amount -= threshold_amount;
// apply the effect
}``````
Because I use >= in comparison, the float precision shouldn't matter that much (they might slow-down of speed-up the effect by some usually negligible factor) - once I cross the threshold, I get the effect and am ready to get it again.
As a bonus, it handles cases when amount per step exceeds the threshold and the effect is applied multiple times within a step.

• TsukaYuriko

#### GMWolf

##### aka fel666
Am I missing something here?
This seems like a perfect job for modulo operator! Why hasnt anyone pointed that out yet?

Code:
``````if ( keyboard_check_pressed(vk_space))
{
counter ++; //increase counter by one
if (counter % 10 == 0) {
//Do something
image_alpha += 0.3;
}
}``````
Then, if you want the fractional number back, just divide counter by 10.

• Homunculus and TsukaYuriko