JSON pretty is altering values

is this a bug?

//payload

{"rates":{"car":0.49}}

//return:

{
  "rates" : {
    "car" : 0.48999999999999999
  }
}

//steps:

Action Type the ⌘C Keystroke
-
Action Filter System Clipboard with JSON Pretty
Store result to System Clipboard.
-
Action Paste

It's not uncommon with floating point numbers unfortunately. The nature of the standard floating point numbers is that 0.49 cannot be represented exactly.

Normally Keyboard Maestro is pretty good at shielding you from this. For example, Set Variable to Calculation 49/100 gives the expected string result of 0.49.

Unfortunately, in this case it is the system [NSJSONSerialization JSONObjectWithData] API which turns the string in to an object structure, which includes an NSNumber representing the best approximation of 0.49. And then the [NSJSONSerialization dataWithJSONObject] turns the object in to a pretty JSON, but it is not as clever as Keyboard Maestro and so doesn't have code to be careful about such rounding errors.

So. β€œIs it a bug?” I would say it's kind of a bug, kind of a poor behaviour in handling floating point numbers. But either way, the bug/behaviour is in the Apple system NSJSON API so there isn't anything I can do to resolve it I'm afraid.

2 Likes

We don't know what your application is, but in cases where you need to store a specific ratio, like 49/100, rather than an IEEE754 floating point value ( see Exposing Floating Point – Bartosz Ciechanowski ) the trick is to store separate integer values for numerator and denominator.

{"ratio":{"numerator":49, "denominator":100}}
2 Likes

Try to store 0.49 as a float here, for example:

3 Likes

Thanks for the quick replies. My macro is intended to beautify JSON, making it easier to review quickly. But I am glad I stumbled on the issue in case I do need to use the step for a more critical process.