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.
JSONExport - rounding weirdness
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller
Re: JSONExport - rounding weirdness
@KimD: So the lines:
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 ]
Code: Select all
Put (1000.001) into dataForApi["quantity_product"]
Put (1000001/1000) into dataForApi["quantity_product"]
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 ]
Re: JSONExport - rounding weirdness
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.
{"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.