{"action":"created","issue":{"url":"https://api.github.com/repos/GaloisInc/json/issues/5","labels_url":"https://api.github.com/repos/GaloisInc/json/issues/5/labels{/name}","comments_url":"https://api.github.com/repos/GaloisInc/json/issues/5/comments","events_url":"https://api.github.com/repos/GaloisInc/json/issues/5/events","html_url":"https://github.com/GaloisInc/json/issues/5","id":122423567,"number":5,"title":"Double vs. Rational in JSValue","user":{"login":"dckc","id":150986,"avatar_url":"https://avatars.githubusercontent.com/u/150986?v=3","gravatar_id":"","url":"https://api.github.com/users/dckc","html_url":"https://github.com/dckc","followers_url":"https://api.github.com/users/dckc/followers","following_url":"https://api.github.com/users/dckc/following{/other_user}","gists_url":"https://api.github.com/users/dckc/gists{/gist_id}","starred_url":"https://api.github.com/users/dckc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dckc/subscriptions","organizations_url":"https://api.github.com/users/dckc/orgs","repos_url":"https://api.github.com/users/dckc/repos","events_url":"https://api.github.com/users/dckc/events{/privacy}","received_events_url":"https://api.github.com/users/dckc/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-12-16T03:58:52Z","updated_at":"2015-12-16T18:27:35Z","closed_at":"2015-12-16T18:27:35Z","body":"I'm using JSON for some expected test results and it's not working for floats.\r\n\r\nI printed out some details and got...\r\n\r\n```\r\nLexerTestCase {input = \"0.91\", expected = [(\".float64.\",JSRational False (91 % 100))]}\r\nRight [(\".float64.\",JSRational False (8196551321814303 % 9007199254740992))]\r\n```\r\n\r\nI'm surprised to see that this package uses haskell Rational to represent numeric literals. My expected test results are parse as:\r\n\r\n```\r\nλ> decode \"0.91\" :: Result JSValue\r\nOk (JSRational False (91 % 100))\r\n```\r\n\r\nBut JS numeric literals are floats, not rationals (details below). My actual test result is 0.91 :: Double. This package provides a JSON instance for Double, but it produces...\r\n\r\n```\r\nλ> toRational (0.91 :: Double)\r\n8196551321814303 % 9007199254740992\r\n```\r\n\r\nwhich doesn't equal my expected results, so my test fails.\r\n\r\n### Details on JS Floats\r\n\r\nThis [JSON package](https://hackage.haskell.org/package/json-0.9.1) cites [Standard ECMA-262 3rd Edition - December 1999](http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf). In section *7.8.3 Numeric Literals*, we read\r\n\r\n> Once the exact MV for a numeric literal has been determined, it is then rounded to a value of the\r\nNumber type.\r\n\r\nand\r\n\r\n> 4.3.20 Number Type\r\n> The type Number is a set of values representing numbers. In ECMAScript, the set of values represents the double-precision 64-bit format IEEE 754 values including the special “Not-a-Number” (NaN) values, positive infinity, and negative infinity"},"comment":{"url":"https://api.github.com/repos/GaloisInc/json/issues/comments/165203971","html_url":"https://github.com/GaloisInc/json/issues/5#issuecomment-165203971","issue_url":"https://api.github.com/repos/GaloisInc/json/issues/5","id":165203971,"user":{"login":"yav","id":12394,"avatar_url":"https://avatars.githubusercontent.com/u/12394?v=3","gravatar_id":"","url":"https://api.github.com/users/yav","html_url":"https://github.com/yav","followers_url":"https://api.github.com/users/yav/followers","following_url":"https://api.github.com/users/yav/following{/other_user}","gists_url":"https://api.github.com/users/yav/gists{/gist_id}","starred_url":"https://api.github.com/users/yav/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yav/subscriptions","organizations_url":"https://api.github.com/users/yav/orgs","repos_url":"https://api.github.com/users/yav/repos","events_url":"https://api.github.com/users/yav/events{/privacy}","received_events_url":"https://api.github.com/users/yav/received_events","type":"User","site_admin":false},"created_at":"2015-12-16T18:27:35Z","updated_at":"2015-12-16T18:27:35Z","body":"Hello,\r\n\r\nusing `Rational` ensures that the abstract syntax looses no precision in the representation.  JSON is just a textual format for representing a certain class of structured values, and while it is often used in conjunction with (Java|ECMA)Script, we didn't want to limit the number representations to what's available there.\r\n\r\nThe issue that you are encountering is that `0.91` cannot be represented exactly as a IEEE 756 number. This means that there is simply no way to write it either as a Haskell `Double` or a `Number` in JavaScript---whenever you write `0.91` you get a number that is a little larger.  This is why `toRational (0.91 :: Double)` gives you the odd fraction, and not `91 % 100` as you might expect.\r\n\r\nI am not sure about the context of your tests, but if you are wanting to extract `Double`s out of some JSON structure, you should be able to parse it out as such.  For example:\r\n\r\n    > decode \"[0.91,10]\" :: Result [Double]\r\n    Ok [0.91,10.0]\r\n\r\n\r\n\r\n\r\n\r\n\r\n"}}