JSONExport - rounding weirdness

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
KimD
Posts: 225
Joined: Wed Jul 08, 2015 5:51 am

JSONExport - rounding weirdness

Post by KimD » Tue Oct 15, 2024 5:08 am

A user has reported a bug in a LC app that I developed four years ago, so I'm back into LC after an 18 month break. Within my app I'm converting Kg values entered by the user into Mt, by dividing the Kg value by 1000. There is no problem when the user inputs a Kg value which is less than 1 million, but if the user enters a Kg value over 1 million then - when they retrieve previously JSONExported data - they see their entered values have been rounded incorrectly. The bug is easy to reproduce with the following code -

Local dataForApi, JSONFile
Put "file:" & specialFolderPath("desktop") & slash & "RoundingWeirdness.txt" into JSONFile
Put empty into URL(JSONFile)
Put (1000.001) into dataForApi["quantity_product"]
Answer dataForApi["quantity_product"]
Put JSONExport(dataForApi) & CR after URL(JSONFile)
Put (1000001/1000) into dataForApi["quantity_product"]
Answer dataForApi["quantity_product"]
Put JSONExport(dataForApi) & CR after URL(JSONFile)

Both Answer dialogues display 1000.001 (the expected result), but the resulting RoundingWeirdness.txt file contains -
{"quantity_product": "1000.001"}
{"quantity_product": 1000}

The 2nd entry in the RoundingWeirdness.txt file is wrong; it should be 1000.001. If the problem was solely with the operation of dividing 1000001 by 1000, then I would have expected the 2nd answer dialogue to also display an incorrect result; but it doesn't. If the problem was solely with JSONExport, then I would have expected JSONExporting 1000.001 to also produce an incorrect result; but it doesn't.

JSONExporting 1000001/1000 does not produce the same result as JSONExporting 1000.001; which it should.

I'm pretty confident that I can easily create a work around for this, but I thought that I'd check whether this was a known issue.

LC 9.6.9rc2 on Windows 11.

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1232
Joined: Thu Apr 11, 2013 11:27 am

Re: JSONExport - rounding weirdness

Post by LCMark » Tue Oct 15, 2024 6:32 am

@KimD: So the lines:

Code: Select all

Put (1000.001) into dataForApi["quantity_product"]
Put (1000001/1000) into dataForApi["quantity_product"]
Are not quite the same.

In the first line '1000.001' is actually treated internally as a string (for various irksome reasons that are very difficult to change), this means that JSONExport sees it as a string and so exports it as a JSON String "1000.001".

In the second line the 1000001/1000 is a math op, so the result of the division is internally a number (floating point double specifically), this means that JSONExport sees it as a number and so exports it as a JSON Number 1000.001 *but* due to the LCB number->string method used to do so, precision is lost and it ends up coming out as 1000.

This has been fixed in LC10 where we've used a much better double->string conversion method.

[ Further, JSON import/export has been completely overhauled in Create 1.0 - where the same rules are used for emitting JSON numbers as the ECMA standards specify for JavaScript ]

KimD
Posts: 225
Joined: Wed Jul 08, 2015 5:51 am

Re: JSONExport - rounding weirdness

Post by KimD » Tue Oct 15, 2024 11:08 pm

Thanks Mark. Great explanation. I've switched to LC 10 and I can confirm that, as you say, the weirdness goes away. With LC10, my roundingWeirdness.txt file now contains -
{"quantity_product": "1000.001"}
{"quantity_product": 1000.001}

Interesting that the first is still a string and the 2nd a number (which you've explained), but I'm sure that I can work with that.

Post Reply