YoYoGames / GameMaker-Bugs

Public tracking for GameMaker bugs
26 stars 8 forks source link

Inconsistencies between math functions and comparison operators #5132

Open YYBartT opened 7 months ago

YYBartT commented 7 months ago

Description

Originating from the following issue: https://github.com/YoYoGames/GameMaker-Bugs/issues/4816

With the fix in the linked issue in place, the sqrt function now considers values in the range [-epsilon, 0] to be equal to 0, though some other inconsistencies remain between the comparison operators and certain math functions, such as sign and floor. The following piece of code shows a few of these inconsistencies:

var _e = math_get_epsilon();  // Default is 0.00001
var _v = -_e + .5 * _e;       // Get a value between -epsilon and 0

show_debug_message("Tests");                            // Tests
show_debug_message($"e: {string_format(_e, 10, 6)}");   // e:          0.000010
show_debug_message($"v: {string_format(_v, 10, 6)}");   // v:         -0.000005
show_debug_message($"v >= 0: {_v >= 0}")                // v >= 0: 1
show_debug_message($"sign(v): {sign(_v)}");             // sign(v): -1
show_debug_message($"floor(v): {floor(_v)}");           // floor(v): -1
show_debug_message($"ceil(v): {ceil(_v)}");             // ceil(v): 0
show_debug_message($"round(v): {round(_v)}");           // round(v): 0

// Third power preserves minus sign
var _s = _v;
repeat(3) { _s = power(_s, 3); }

show_debug_message(_s);                                 // -0.00
show_debug_message(sign(_s));                           // -1

In the code above, the underlying values preserve the sign which the math functions take it into account, while checking equality with 0 using a comparison operator returns true. If a value is considered >= 0, the result of flooring it cannot be -1.

test_math_epsilon.zip

Expected Change

The results of comparison operators and math functions are consistent

Steps To Reproduce

  1. Start GameMaker
  2. Copy-paste the code in the description into the project
  3. The debug output shows the inconsistencies as shown in the comments

How reliably can you recreate this issue using your steps above?

Always

Which version of GameMaker are you reporting this issue for?

2024.2.0 (Monthly)

Which platform(s) are you seeing the problem on?

Windows

Contact Us Package Attached?

Sample Project Added?

backYard321 commented 7 months ago

If I understand this correctly: if number == 5 is true, floor(number) and ceil(number) both ought to return 5 as well, and actually take into account the epsilon.

I noticed this recently with floor(); didn't report it because I wasn't sure if I was missing something! I'll get situations where 0.99999 or whatever equals 1, but floors to 0, so to get around it I have to do something like:

var _round = round(number)
if number == _round
    number = _round
number = floor(number)

Not great! So hoping this gets changed before it comes back to bite me.