Page 1 of 1

Why Does JS Coerce X.00000 to an Int?

Posted: Tue Aug 27, 2019 5:21 pm
by FrancoBlanko
I've been having a nightmare trying to place notes through the JS LiveAPI.

If i sent a note position of 0.0 like this: parseFloat(Number(0.0).toFixed(5)) JS will output it as an Int, 0, which Ableton then kicks up a fuss about as it's expecting a float for the position argument. Ruins my whole message and kills the function call.

I finally solved it using toPrecision() method of Number like this: parseFloat(0.0).toPrecision(5), and it will work. But what the hell... It's only 0.00 that makes any trouble, all other 'integer' positions work just fine using toFixed() inside parseFloat().

I initially started using parseFloat() and toFixed() because i was getting scientific notated numbers occasionally, which would then mess up my messages. I also noticed that the msg_float() built-in function of JS was chopping off significant digits in the fractional part of my numbers, so had to send them in as strings to get the full 4-5 digits i wanted. Bloody pain in the arse. I only even started using JS cos sending the messages in series to live.object was giving me an even worse headache what with the stupid threading in Max.

Bit of a rant, but does anybody know why this stupid number massaging happens inside JS>?

Re: Why Does JS Coerce 0.00 to an Int?

Posted: Wed Aug 28, 2019 11:35 pm
by FrancoBlanko
Bloody useful lot here aren't you

Re: Why Does JS Coerce 0.00 to an Int?

Posted: Thu Aug 29, 2019 3:52 am
by Tarekith
Just because no one in the last 24 hours who might be able to reply has seen your post is no reason to get snarky about it. We're a pretty chill group and when people have info they can share they generally do. Have a bit of patience.

Re: Why Does JS Coerce 0.00 to an Int?

Posted: Mon Sep 02, 2019 1:36 pm
by FrancoBlanko
I found this which is pretty comprehensive about the inadequacies of number arithmetic in js:

https://www.youtube.com/watch?v=MqHDDtVYJRI

Still doesn't explain max dropping the fractional part of zero as a float. I'll have to do some tests and see which conditions cause it.

Re: Why Does JS Coerce 0.00 to an Int?

Posted: Mon Sep 02, 2019 5:59 pm
by FrancoBlanko
Looks like i cracked it... using someNumberVariable.toFixed(6) and then passing that to Live in the function call works fine even though it is converting the number to a string, because it will then be reconverted to a number where Live expects a number, and it will have the right precision for mysterious reasons. The parseFloat() function is unreliable and may return exponential notation. If i run into problems in future with type conversion i can use the + operator on the string to force it to become a number in place. Debugging was quite difficult until i realised that the post() method of the JS object rounds floating point numbers to 2 decimal places, which can be fixed using the toFixed() method on a number, thus causing post() to output the correct value as it is now seeing a string. What a faff. Still haven't found an answer about the coercion of 0.0 into an integer, JS just seems to do it for no point at all.

Re: Why Does JS Coerce 0.00 to an Int?

Posted: Mon Sep 02, 2019 6:53 pm
by [jur]
I edited your posts' sizes back to "normal"; it was very eye-killing!

Re: Why Does JS Coerce X.00000 to an Int?

Posted: Sat Sep 07, 2019 2:27 pm
by FrancoBlanko
Right, from what i can gather this is happening on ANY number - not just 0.00 like i originally thought - that has a fractional part which is all zeroes due to the way Javascript handles numbers, where they are stored as double-precision floating point. This means that even if a number is representable as an integer it is actually a 64-bit float behind the scenes (for most numbers). So what happens is that Javascript can see eg. 4.0000 as an Int via the .isInteger() method and will drop the fractional part if it thinks it's not needed, which is why Live will get an Int when it wants a Float and makes a fuss about it. Using .toFixed(6) handles the precision of the positions coming from Live's MIDI clip getter methods just fine, and seems to trick JS into sending a Float to Live via the setters because it coerces the String literal which toFixed() outputs to a Float, keeping the fractional part even though it is only zeroes. What a faff. Got my thingy working well now anyway after all this. A million thanks for the help goes to ME and my tenacious nature. Tickity tonk.