google / jsonnet

Jsonnet - The data templating language
http://jsonnet.org
Apache License 2.0
6.98k stars 440 forks source link

Add failing test for formatting integer #997

Closed GeorgeMac closed 2 years ago

GeorgeMac commented 2 years ago

This isn't strictly a pull request. More a demonstration of an issue I am observing.

When formatting some integers using %d, I am finding incorrect results for certain inputs. I added an example failing case in this PR.

I am unfamiliar with this codebase, but I've tracked it down as far as: https://github.com/google/jsonnet/blob/914f636a575f9aef68089ab7de93601eecddd325/stdlib/std.jsonnet#L517-L522

For example:

➜  jsonnet -e "local a(n) = (if n == 0 then '' else (a(std.floor(n / 10)) + (n % 10))); a(1650391876808854107)"
"1650391876808854086"
➜  jsonnet -e "local a(n) = (if n == 0 then '' else (a(std.floor(n / 10)) + (n % 10))); a(1650391876808854107) == '1650391876808854107'"
false

I couldn't see an issue for this open anywhere; I am happy to open an issue if that is preferred.

I saw https://github.com/google/jsonnet/issues/880, which calls for more extensive testing. Which feels related, but not strictly inclusive of what I am seeing here.

GeorgeMac commented 2 years ago

Just in case this is helpful context, this also produces an unexpected (?) result:

➜  jsonnet -e '1650391876808854107'
1650391876808854016
sparkprime commented 2 years ago

This is expected because Jsonnet numbers are all doubles.

sparkprime commented 2 years ago

So I suppose the behaviour of %d is consistent with the same behaviour in Python, if you hand it a double instead of an int.

sparkprime commented 2 years ago
Python 3.10.7 (main, Sep  8 2022, 14:34:29) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("%d" % 1650391876808854107.0)
1650391876808854016
>>> 
sparkprime commented 2 years ago

Even this doesn't work:

dcunnin@dcunnin1:~$ jsonnet -e 1650391876808854107
1650391876808854016
GeorgeMac commented 2 years ago

Good to know. I was using it to print unix timestamps, and then another system was expecting those timestamps to be precisely as expected. I moved away from relying on that mechanism in the end, so I wasn't blocked.

Shall I close this for now, if it's working as expected?