• Hey! Guest! The 37th GMC Jam will take place between May 28th, 12:00 UTC and June 1st, 12:00 UTC. Why not join in! Click here to find out more!

GML Convert precise number from string

Is there any way to convert string like "‭0.01780942‬" to a number ?
I used real() function but it automatically rounds to "0.02".

code (file_read is a string):
file_read = real(file_read);
DECODE_fileRead: 0.02
(file_text_read_real() gives the same result)


ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
The function does return the precise result, is is rather that you are converting it to string via regular string() (which is 2-point precision) rather than string_format
Is it possible to accurately re-cast a real that has been cast as a string using string_format()?

Here's what happens when I do this (the string_trim() function is available here(https://www.gmlscripts.com/script/string_trim) :

string_trim(string_trim(string_format(17.5989875,string_length(string_format(17.5989875,string_length(string(17.5989875)),string_length(string(17.5989875)))),string_length(string_format(17.5989875,string_length(string(17.5989875)),string_length(string(17.5989875)))))),"right","0") = "17.5989875"  //okay good so far

//But then, if I wanted to re-convert it back to a real...
real(string_trim(string_trim(string_format(17.5989875,string_length(string_format(17.5989875,string_length(string(17.5989875)),string_length(string(17.5989875)))),string_length(string_format(17.5989875,string_length(string(17.5989875)),string_length(string(17.5989875)))))),"right","0")) = 17.60 //Why does it then round a floating point string?
Forgive the complexity of the above code--I needed a way to ensure that all the decimal places would be preserved. I then had to trim the leading spaces and trailing zeros.

Is there a real_format() function of some kind?


You can't and won't preserve all the decimal places for reasons explained here. The article is for Python, but the same thing happens everywhere that floating points are used, including GML.


🐧 *penguin noises*
GMC Elder
real() should be able to interpret any string that contains a valid real number, but if you lose precision...
  1. Find the decimal point, and split the string into two parts (each with only numbers)
  2. Convert the part left of the decimal point with normal real. Let's call this whole.
  3. Count the number of digits in the part right of the decimal point (which we'll call part). Let's call this theta.
  4. Compute power(0.1,theta) - call this value epsilon.
  5. Do a normal real on part (resulting in a number with theta digits, aka huge) and multiply it with epsilon (thus turning it into a tiny number). This is your new fractional part party.
  6. The total number (fractional + integer part) simply is whole + party.
This will fail if epsilon is smaller than the maximum possible precision. You might want to cap theta (and thus the number of digits you will real on when computing party) to a value like 10 (doubles has a precision of ~15 digits - you can go closer to 15 if you want, but you'll lose precision fast through all sorts of effects you can find better explained in other places and you will just end up with incorrect results)