# Custom rule for decoding JSON input with Jason

I am working with an API that provides currency conversion rates in JSON like this:

``````{
"fx_rate": 1.01
}
``````

When reading from that API, I get a map `%{"fx_rate" => 1.01}` and as far as I understand I immediately lose precision because I convert the literal representation of “1.01” to float 1.01 which might not be the same internally.

I’d like to make sure that Jason does not parse this 1.01 to float but instead returns it as string `%{"fx_rate" => "1.01"}`. Then I have exact representation and can use `Decimal.new` to make further computations.

Is there a way to advise Jason to treat that field as string?

I was thinking about making a plug that changes the request body still represented as a string. It would find the `"fx_rate": 1.01`, and change it to `"fx_rate": "1.01"` with a regular expression, so that Jason can later do its job.

But I figured I will ask here first, if you have less hacky ideas

1 Like

If you want precision in decimals, you can use fixed point arithmetic.

Simple idea - represent everything in integers - multiply everything by 10 n where n is the number of precision digits .

``````# i want 2 digits precision so i will multiply with 100
0 * 100 = 0
0.5 * 100 = 50
3.1415 * 100 = 314
``````
``````{
"fx_rate": 101 # 1.01 * 100
}
``````

This technique is used in finance, gaming, graphics, etc

Have you seen the `floats: :decimals` option to `Jason.decode/2`? That might be what you’re looking for.

uses `Decimal.new/1` to parse the binary into a Decimal struct with arbitrary precision.

Edit: For Plug, that looks like this:

``````  plug Plug.Parsers,
parsers: [:json],
json_decoder: {Jason, :decode!, [[floats: :decimals]]}
``````
5 Likes

There is the `floats: decimal` option, but out of curiosity, would it ever really be a problem if you just use `Float.to_string`.

``````> Float.to_string(0.1)
"0.1"
> Float.to_string(0.01)
"0.01"
``````

While “The closest representable number to 0.1 is 0.1000000014” it is still converted to `0.1`

Thank you guys! I missed the floats: :decimal!

This plug example has now been added to the docs.

https://hexdocs.pm/plug/Plug.Parsers.html#module-examples

1 Like