herman
Hello ![]()
I was working on upgrading one of our apps to 1.17 this morning and came across the compiler warning.
pattern matching on 0.0 is equivalent to matching only on +0.0 from Erlang/OTP 27+
This seemed fine and is no problem to patch, in our case if +0.0 is possible technically -0.0 is possible.
iex(1)> 1.0 * 0.0 == +0.0
true
iex(2)> -1.0 * 0.0 == -0.0
true
Since it’s a warning, for a future version, I can understand that +0.0 would match for -0.0
-1.0 * 0.0 == +0.0
true
However, it will be risky for us to match only on +0.0, for if/when it becomes a requirement.
So we would want to add the matches for -0.0, however
def format(number) when is_number(number) do
case number do
#I've flipped the order on both to test
-0.0 -> Integer.to_string(number)
+0.0 -> Integer.to_string(number)
end
end
Will generate a compiler warning
warning: this clause cannot match because a previous clause at line 9 always matches
Outside of ignoring these warnings, would leave us in a place where we can only match on +0.0, and hope the warning remains true for future versions (both +0.0 and -0.0 being matched on +0.0)
Is there a recommended way to tackle this? What will be the expected behaviour from OTP/27 onwards? Should we wait until we upgrade to OTP 27 where we could possibly have different matches?
Trending in Questions
Other Trending Topics
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
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #hex
- #security











Showing Posts 1 to 5- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
al2o3cr
One option would be to match
abs(number), which will ensure that 0.0 and -0.0 are treated identically.The “best” answer ultimately depends on your application; in general, matching floats with
==can cause unexpected bugs.For instance, the dreaded “almost zero but not quite” and the non-associativity of floating-point math:
The usual approach for dealing with this is to define a “tolerance” around zero that is acceptable - this is strongly application-dependent, so I can’t tell you the right value for your application.
Beware: if you take that route, make sure you’re applying it consistently or you can end up with REALLY weird bugs like this one in Minecraft:
Hermanverschooten
That’s why I detest floating point
josevalim
The trick to remember is that pattern matching uses
===.==does type coersion between numbers and therefore0.0 == -0.0 == 0.Therefore, regardless of the OTP version:
x == 0is_float(x) and x == 0<<x::float>>and check if the first bit it zero. From Erlang/OTP 27, you can match on either +0.0 or -0.0 directlyfmn
apologies for slight offtopic, but i found this post crazy interesting, especially this part:
herman
Thank you! That makes complete sense