benlime
Hey guys,
I have a short and simple question, which I am currently unable to figure out using the documentation of the Jason library.
I have a struct which contains some keys with values of the Decimal struct. I would like to have the Decimal struct (I am using the Decimal Library for it) always converted to float when encoding to JSON. So far I only know that I would have to implement the Json.Encoder protocol and have the encode method to call Decimal.to_float(value). But I am not sure how to do that? How do I implement the protocol?
I have tried to just make a file like this:
defimpl Jason.Encoder, for: Decimal do
def encode(struct, opts) do
Jason.Encode.map(Decimal.to_float(struct), opts)
end
end
However, this code never runs. Can anybod help? ![]()
Thanks guys.
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
Hi everyone,
I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding.
I sta...
New
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
I’m working on a small exercise involving update_in/3, and I came up with this solution:
data = %{
name: "Periodic Table",
category:...
New
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication):
toke...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ai
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #metaprogramming
- #hex










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
NobbZ
Please do not use floats. You will use all the precision you initially got by using decimal. Please do either use a String or dump into a JSON object.
Aside of that, you should use
Jason.Encode.float/1. From what I can see in the snippet you posted, the code should crash rather than not being run. Can you therefore reproduce the problem in a fresh project and put it on github?benlime
Thanks for your reply. Can you describe why using a floating point number in JSON is a bad idea? I am using
Decimalinternally to handle money values and want to return those to the frontend just for displaying in the view. Having the number as a string representation feels wrong to me. However, the default encoding encodes the value to a string. I am not sure where this logic comes from.edit: Okay I found a pretty good explanation of why I should not use floating points on StackOverflow. I get it - but just for my personal knowledge, the question still remains - even I would not use it anymore.
I don’t think a demo project is needed. I just can’t figure out how to make the code run. I only created a file
decimal_encoder.exwith the protocol implementation. But I need to use or register the implementation anywhere so that Jason knows it should use my decoder, don’t I? And this is where I am stuck.NobbZ
Floating point numbers might have their right to exist in JSON, but definitively not when your datasource is a
Decimal, asDecimalallows for very exact values, which float doesn’t.This is good.
But to be honest, in JSON the only way to represent numbers in a safe way, as JSON does not differentiate between integers and floats, but knows only about numbers. So numbers that look integral might get coerced to float without you beeing able to control.
From
jason:https://github.com/michalmuskala/jason/blob/master/lib/encoder.ex#L204-L210
So you can not change it.
And here we already have a problem. What is encoded as 1 Euro and 5 cent might get rendered as
1.05in the JSON, but as this probably not an exact value in Float this might get loaded as1.04999999(or similar) and displayed as such. Or even worse, the client truncates or rounds, or does other things out of your control.Your user has the right to get the same (or at least equivalent) information that you are working with, especially when its the users money!
benlime
Thank you so much for your explanation. This totally makes sense and I’ll stick with strings for representing money values.
I was looking at the Jason Source as I was expecting something lime this, but I must have missed it. Thanks for sharing this.
NobbZ
I knew where to look
I already assumed Jason where implementing for Decimal when I’ve seen that decimal is an optional dependency of it.
Also
defimpls are usually in the same file as the struct or the protocol, and as Jason does only define the protocol it was clear where to look, as we can safely assume that @michalmuskala organizes his code idiomatically.OvermindDL1
Ack!!!
Among others!
Never ever ever ever ever use floats in relation to money, ever ever ever!
/me hopes they were clear enough ^.^;
benlime
I think you missed one „ever“. (I got it, I got it.
)
zenw0lf
Hmm, I thought that the real problem with floats was trying to operate with them, not displaying them per se.
I know the famous:
0.1 + 0.2 # == 0.30000000000000004, but if you are operating on Decimals in Elixir and do something like:And then convert the result to a float, it’ll be present just right, as
0.3.What I’m trying to get at, in the end I always have to use
parseInt, parseFloat or Numberon the frontend to convert those decimal strings into numbers, because you usually need those values for validations, limits, steps, etc.Honest question:
Is there really a problem when going from a string representation to a float?
Is there an example of a decimal string representation that when converted to a float loses precision? Something like having
"1.05"=> converts to float =>1.049999?NobbZ
There are enough, just take
0.3, you can not represent that value as float32, the same is probably true for float64, but you can at least have a closer approximation.Play around with the float converter, it shows you what is possible and what is not.
Also, just as an exercise. Try to find
nandm:0.3 = m / (2 ** n)Even though that is not the real representation, it will give you an estimate what the problem is.
benwilson512
Sure, here’s a concrete example:
Suppose you have a service where people want to send you numbers, and you’re going to do some kind of processing with those numbers, and then send back a result. Suppose it’s super simple, like a math test for kids where they’re asked to round a number.
The task is: Round “2.675” to the nearest hundredths place.
You take that value, and parse it to a float:
Yay! that looks right!
Oh no…
This happens because it isn’t actually 2.675, it’s
2.67499999999999982236431605997495353221893310546875and Elixir is nice and displays something more friendly.Yes, if you care about precision at all. To be clear, plenty of times you don’t care about precision. Maybe you’re doing geolocation stuff where precision is carried as a separate term anyway, maybe you’re doing something in a GPU with floating point math. But if people want you to treat the number as it is written, you can’t convert it to a float, at all.