15

I am trying to round a Float in elixir to 2 decimal places.

If I have the number 12.555, I would like my rounding function to return 12.56

I originally thought that the Float.round was what I wanted but this function does not always return the answer I would like.

For example...

iex()> Float.round(12.555, 2)
12.55

I know that I can get this done with a makeshift function but I thought that there must be a better solution.

My current solution is...

iex()> round(12.555 * 100) / 100
12.56

This does the job but like I said, I just wanted to know if there was a better solution.

Thanks in advance

RobStallion
  • 1,624
  • 1
  • 15
  • 28
  • 4
    This has nothing to do with Elixir, but with IEEE 754 floating point numbers; see also https://hexdocs.pm/elixir/Float.html#round/2 – coproc Apr 08 '19 at 20:04
  • @coproc please feel free to update the flags if you think that they are not accurate. – RobStallion Apr 09 '19 at 07:45

2 Answers2

15

Because of the way floating point numbers work, if you want precision, including controlling rounding algorithms, you need to use a library such as Decimal:

12.555
|> Decimal.from_float()
|> Decimal.round(2)

Output:

#Decimal<12.56>

You can then use functions like Decimal.to_string/2 for printing or Decimal.to_float/1, but beware that to_float/1 is also an imprecise operation and could fail.

Adam Millerchip
  • 20,844
  • 5
  • 51
  • 74
4

Float.ceil/2 might help you with this if you don't want to use a library

iex> 12.555 |> Float.ceil(2)        
12.56
BlueGene
  • 1,071
  • 1
  • 20
  • 30
  • Not if you need sensible decimal behaviour. `Float.ceil(0.2, 1)` and `Float.ceil(0.3, 1)` both produce `0.3`, for example. https://floating-point-gui.de/ – Adam Millerchip Jun 11 '20 at 16:20