This is a reduced test case. The actual macro would receive a value from the Front Browser's current page.
When I run Math.floor(101.01) directly in the browser's console*, it returns 101 as expected.
(*I tested in Safari and Chrome.)
Funny enough, if I use Keyboard Maestro's native FLOOR() I do receive 101.
ie: FLOOR(101.01) results in: 101
Also, I'm aware of the funniness in JS re: floating point calculations. But I wouldn't think that has anything to do this, since it would seem the browser is processing Math.floor() and Keyboard Maestro is adding the .0. Or maybe it's the browser adding that .0 ?
The result is correct, and you have not specified any formatting so it is entirely reasonable.
Or you could use Keyboard Maestro’s Set Variable to Calculation action with the Formatting option to force the formatting to your desired precision.
In C for example, the floor function is defined as:
double floor (double x);
That is, it takes a double width floating point and returns a double width floating point.
Also, it depends on the allowable types of the language. For example, in Keyboard Maestro all variables are strings. In other languages, they might have only floats and strings, with no specific type for integer.
Yes. Really, if you want a specific formatted output this would be the most robust solution.
Or you could do the FLOOR function in a Keyboard Maestro calculation, and Keyboard Maestro takes pains to never return a calculation in a format like 123.0 (unless you specify the format explicitly of course!).
That makes sense. I can definitely see, in principal, why floor()shouldn't automatically imply literally converting a float to an int.
I probably shouldn't have written what I did above. Since that was more of a perception about the result rather than what is really going on under-the-hood. Especially considering all numbers are floats in JS (with the exception of BigInt that @ComplexPoint mentioned).
AFAIK, that output from Safari is a number, not a string. But it can be coerced into a string, as you suggested.
And that was because I didn't realize AppleScript was sitting in the middle and treats this case differently than Safari.
Yes, I used that at one point too. It also worked as expected.
Thanks for this.
I'm still just a little curious about why browser JS engines choose to return 101 while AppleScript running JS (for example) returns 101.0 ?
Here's what I found:
Although, unless I'm missing something (which I might be), this still doesn't exactly answer why browser JS engines choose to not show the decimal and ever to its right, while other JS engines do.
AppleScript can handle real or integer types. When converting a real to a string, it adds at least one decimal digit, presumably because this ensures the reverse translation would convert it back to a real instead of an integer.
set v to 101.1 - 0.1 -- displays as 101.0 of class real
set v to 101.0 -- displays as 101.0 of class real
set v to 101 -- displays as 101 of class integer
class of v
Then as a real it is converted to a string (for display or for placing in a Keyboard Maestro variable) by AppleScript, hence it gets “.0”.
One thing to bear in mind is that console.log,
(It's just a legacy library method which was commonly supplied in early browser embeddings of JS, and which is often implemented in some form or another by commercial suppliers of other types of JS embedding)
Script Editor, for example, provides its own (and distinct) stringification of
script return values. Again, not part of JS, just a supplier-defined utility.
If you need a particular stringification, you can write your own. Any JS Number value is a fixed width Float, so there's not much complexity to deal with.