GML Trig functions precision issues

HalRiyami

Member
Not quite sure where to put this but I figured since it's related to GML this is a suitable sub. I'm using the latest version of GMS 2.

So after about a few hours debugging my code to see why I had relatively huge rounding errors in my scripts, I was able to trace the source of my problems to the trigonometric functions in GMS 2. It seems that when feeding the functions large numbers, you end up with "major" rounding errors, I say "major" because they are actually pretty small but when precision is required they do compound like in my case. I was luckily able to find a workaround (use "mod 360" before feeding the number into the functions) but I still thought this is worth discussing.

Here is a comparison between GMS 2 output and WolframAlpha:
FunctionGMS 2WolframAlphaError (wa - gms2)/wa
var a = dsin(123456.123456);
-0.404558420181274​
-0.40476727150660​
5.16E-04​
var b = dsin(123456.123567);
-0.404558420181274​
-0.40476549998613​
5.12E-04​
var c1 = 123456.123456 mod 360;
336.123456000001​
336.123456000000​
-3.04E-15​
var d1 = 123456.123567 mod 360;
336.123567000002​
336.123567000000​
-6.09E-15​
var c = dsin(c1);
-0.404767006635666​
-0.40476727150658​
6.54E-07​
var d = dsin(d1);
-0.404765278100967​
-0.40476549998630​
5.48E-07​

You can see that there is a significant loss in the precision of dsin when the input is large and this affects the entire spectrum of the trig function (degrees and radian versions).
I'm not sure if this is known and accepted or if GMS 2 should implement mod 360/mod 2pi in these functions.

Does anyone know anything about this?
 

chamaeleon

Member
It is not just when the input is large, it is also when the input is close to but not exactly zero, pi/2 (for cos), etc.
GML:
var a = 0.000015;
for (var i = 0; i < 9; i++) {
    show_debug_message(string_format(a, 0, 10) + " -- " + string_format(sin(a), 0, 10));
    a -= 0.000001;
}
Code:
0.0000150000 -- 0.0000150000
0.0000140000 -- 0.0000140000
0.0000130000 -- 0.0000130000
0.0000120000 -- 0.0000120000
0.0000110000 -- 0.0000110000
0.0000100000 -- 0.0000100000
0.0000090000 -- 0.0000000000
0.0000080000 -- 0.0000000000
0.0000070000 -- 0.0000000000
 

ophelius

Member
Maybe GM only uses 16-bit precision for floats?

Edit: No I checked, from GM's manual: "All real numbers are stored as double-precision floating point values"

This is strange, I'm real curious what is going on here
 
Last edited:

HalRiyami

Member
Yes. According to the manual "Real numbers in GameMaker Studio 2 are considered double-precision floating-point numbers " so I don't know where this error is coming from.
If you look at the first two rows in my table you'll see that even though the input is different, the output in GMS 2 is the same, similar to what chamaeleon showed.
 

ophelius

Member
Yes, in both your table and chamaeleon's output, the precision level where it's breaking resembles the precision roughly of a 16-bit float, at least that's what I remember the precision to be around 5-6 decimals when I was coding in QB 4.5 a long time ago, which is a 16-bit environment.
This looks like a bug to me
 
H

howfastyes

Guest
@HalRiyami, can you check my topic with same issue but with small numbers, maybe you can help.
 

Yal

šŸ§ *penguin noises*
GMC Elder
Maybe GM only uses 16-bit precision for floats?

Edit: No I checked, from GM's manual: "All real numbers are stored as double-precision floating point values"

This is strange, I'm real curious what is going on here
GM's built-in variables (x, depth, image_speed etc) are stored as int32s, so there's a possibility some of the built-in maths functions use 32-bit floats behind the scenes.
 

chamaeleon

Member
I'll just say in this topic too, if someone feels strongly this is a bug, they should probably file a bug report. I don't feel strongly about having accuracy down to that level myself, but I'm not measuring angular distances in the proximity of dozens of meters on a sphere the size of earth, so I'm not impacted very much.
 

ophelius

Member
GM's built-in variables (x, depth, image_speed etc) are stored as int32s, so there's a possibility some of the built-in maths functions use 32-bit floats behind the scenes.
The errors in precision don't indicate 32-bit floats, they are way less accurate than that


I'll just say in this topic too, if someone feels strongly this is a bug, they should probably file a bug report. I don't feel strongly about having accuracy down to that level myself, but I'm not measuring angular distances in the proximity of dozens of meters on a sphere the size of earth, so I'm not impacted very much.
Either way, GML is a 64-bit language and should have that level of floating-point accuracy, whether or not most people need that kind of precision.
 
This has got me wondering if you might get different results on different machines. I tested sin functions on my machine with gms1.4, and got different results from what HalRiyami got. Is it because of a different gms version, or becauase of the machine or maybe target platform?
 

chamaeleon

Member
Either way, GML is a 64-bit language and should have that level of floating-point accuracy, whether or not most people need that kind of precision.
No disagreement from me. But you seem like you care strongly right now, so I assume you've filed, or are in the process of filing, the bug report to make it happen? :)
 

chamaeleon

Member
This has got me wondering if you might get different results on different machines. I tested sin functions on my machine with gms1.4, and got different results from what HalRiyami got. Is it because of a different gms version, or becauase of the machine or maybe target platform?
The HTML5 version uses the Javascript trigonometric functions and have the full 64 bit double accuracy, for whatever it's worth.
 

ophelius

Member
No disagreement from me. But you seem like you care strongly right now, so I assume you've filed, or are in the process of filing, the bug report to make it happen? :)
Yes, I care about this. I will file a bug report, I assumed HalRiyami did so by now, but I'll file one too
 
H

howfastyes

Guest
I've reported my issue with arctan2() function and attached example project with working formula for HTML5 export but not working for Windows export.
I don't think they will do anything with this but we will see.
 

HalRiyami

Member
I have submitted a bug report so let's hope this gets fixed.
@flyingsaucerinvasion Just like @chamaeleon said, I had a javascript version of the code and it ran perfectly fine on my browser so it must have something to do with the native trigonometric functions.

@howfastyes I looked at your thread. Seems like you have the same issue with the native trigonometric functions.
 
H

howfastyes

Guest
Just like @chamaeleon said, with HTML5 export those trigonometric functions return "proper" output, exactly same formula fails with Windows export.
 
H

howfastyes

Guest
It's strange, yes but i'm not surprised after a week fighting with this issues, when 0.00000001 = 0, and 0.99999999 = 1 everything is possible :) I hope YYG will take a deep look into this issues.
 
Top