Animcurve final value

Azenris

Member
How come when creating an animcurve the final value is inaccurate.

eg. if you make an animcurve for cubic_in and you use the values from 0 to 1
if you inspect the data with
GML:
var _test = animcurve_get( curve_cubic_in );
it will show the final point as 1.00017619132996.

why cant it just literally drop the value from the editor in.



Or am I looking at this wrong :]
I dont mind the values between. but the first value and the last value eg. posx=0 and posx=1
should be the literal values in editor? atleast if an int
 

Azenris

Member
but its an int in the editor, why cant it just be an int for the points struct
I get the floating point stuff (i thought i do anyway)
its not like there is math happening. its a value in the point struct in a points array
meh, i wrote some code to wrap it anyway. i was just curious.
 

Roldy

Member
The Manual list the data types available in GML:
Data Types

Note that 'integer' is not on the list, only 'Real.' GMS internally may represent a Real as an int, float or double but from a language and user standpoint there are only Reals. How the Real is represented internally may differ per platform.

About the only time you can reasonably expect something to be an 'integer' is in the case of literals and constants (enums).

You can set the GMS internal epsilon which largely determines the precision of the comparison operators:

math_set_epsilon
math_get_epsilon
 
Last edited:

Azenris

Member
but surely a float can represent 1 :D
maybe i misunderstand how GM makes the data internally

I just assume when I put in 2 values for a curve [min, max]
that at posx = 0 then the value is min and
that at posx = 1 then the value is max

like
GML:
// literal value
if ( posx <= 0 )
{
    return min;
}

if ( posx >= 1 )
{
    return max;
}

// float inaccuracies can apply here
return some_internal_gm_surve_cals( posx, min, max )
I just dont seem to understand how my input value of 1 in the editor causes gm to represent it in the debugger as the inaccurate number.
maybe am i wrong it cant store 1?



but the max is stored in the struct as not 1, thats what i dont understand. since its just copying my IDE value i insert? to generate the struct data for use in runtime
 

Roldy

Member
It is complicated and how they implement it internally should not be a concern as you should expect everything to be a Real, as that is the only data type involved.

Take a look at the machine epsilon for binary single and double precision:
Machine Epsilon

Can those numbers (e.g. 5.96e-08 ) evenly divide into 1?
 

Roldy

Member
Dunno if this image helps explain what I mean
View attachment 39318
Ok so what can you assume from that? I think a safe assumption is that 'value' is not an integer. The editor is nice and keeps it clean for you.

If you typed '1.5' in the editor you can't expect the internal value to exactly be '1.5' anymore than you can expect it to be exactly '1.'
 

Azenris

Member
i guess thats where my confusion lies, I wouldnt expect high precision numbers to be exactly the same, but I just assumed 1 would. :<

ok im even more confused :p
I changed the value to 2 and it shows exactly as 2. then I changed it back to 1 and now it shows as 1.
now I cant get the weird 1.xxxx
 

Roldy

Member
i guess thats where my confusion lies, I wouldnt expect high precision numbers to be exactly the same, but I just assumed 1 would. :<

ok im even more confused :p
I changed the value to 2 and it shows exactly as 2. then I changed it back to 1 and now it shows as 1.
now I cant get the weird 1.xxxx

I once worked on a companies proprietary editors that were written internally to use the empirical system (feet, yards, inches, lbs etc..), and was tasked to allow the editor and tools to optionally work in metric units as the toolset was licensed internationally. The engine had to internally continue to operate with the empirical system (owners demand).

The code base was about 3 million lines, which comprised about 4 different editor/tools. All with GUIs and input/output files that had to now accept and output metric units while converting everything to empirical internally, back and forth. Worse is they had a proprietary scripting language that now also had to be able to accept metric literals (but be converted to empirical internally), as well as toolset plugins for 3rd party tools like Max and Maya.

Even if the owner hadn't demanded the internal code remain based in empirical units, converting the internal code itself to work with arbitrary units or metric units was a virtual impossibility. Within the millions of lines of code where 10's of thousands of literal numbers, written over decades by hundreds of different people. Knowing which of those were just magic numbers and which represented spatial/mass units was impossible.

I never finished that task. It worked 99.99% of the time, but that still left hundreds of instances where things just 'broke down', especially at the user level experiencing things like you are pointing out in this thread.

This was an extreme case where the imprecision of floats becomes obvious. However, even without converting units, that imprecision is present when dealing with binary floats.

EDIT: What is really messed up is that was a long time ago, but occasionally I find myself still thinking about it! Ooh, I could do this or that. That company doesn't even exist anymore and I am still thinking about their problems.
 
Last edited:

Slyddar

Member
Normally a solution of "that's how it is due to floating point discrepancies", is the end of the conversation. In this case though, understanding floats and how they work aside, as an end user, it seems reasonable to expect once you enter the values in the curve editor, that the output will equal the values you entered. Even if Yoyo has to internally modify the values to ensure points in the list match points in the realtime, especially when they are end points.

Sure there is a mathematical reason why they don't match, but for the end user expecting a value to be what the curve shows it should be, that is the more important factor. I'd suggest you submit it as a feature request, or even though it's not a bug, it actually could be defined as one from a user perspective, so maybe as a bug too. They may agree, they may not, but you can at least pose the question.
 

Roldy

Member
Normally a solution of "that's how it is due to floating point discrepancies", is the end of the conversation. In this case though, understanding floats and how they work aside, as an end user, it seems reasonable to expect once you enter the values in the curve editor, that the output will equal the values you entered. Even if Yoyo has to internally modify the values to ensure points in the list match points in the realtime, especially when they are end points.

Sure there is a mathematical reason why they don't match, but for the end user expecting a value to be what the curve shows it should be, that is the more important factor. I'd suggest you submit it as a feature request, or even though it's not a bug, it actually could be defined as one from a user perspective, so maybe as a bug too. They may agree, they may not, but you can at least pose the question.
I mostly agree with what you are saying; however, from an 'end user' editor perspective the numbers are exact. He typed '1' and the editor shows '1'. When inspecting those number internally at runtime, from a 'end user' engineer perspective we know the number may not be exact.

You can enter many numbers in text form that when represented as a float with limited precision CANNOT exactly be the number entered. The editor may do nice things like store the number in its string format or a decimal format so it doesn't suffer from float precision problems; and we can even do that for data files. However, if we want to do computation on it with any reasonable efficiency and convert it to a floating precision, then we are limited by that precision.

I agree though. Post a bug, let them figure it out.

If I had to guess at OPs original problem it would be that he moved the end point with the mouse, which resulted in the 1.0000179 number ,which is a result of the size of the graph window and resolution of the display, and the editor was being 'nice' and showing '1' in the text field. But maybe not. Post a bug.
 
Last edited:
Top