How to convert string to integer with decimal point

How can I convert string to integer with decimal point.

It works.

String.to_integer("100")

It does not work.

String.to_integer("100.0")
** (ArgumentError) argument error
    :erlang.binary_to_integer("100.0")

I would like to know how to.

Integers do not have a decimal point, you either want String.to_float/1 or Float.parse/1.

2 Likes

If a number has a . then it is a float and not an integer. What you are looking for is something like this:

{number, _char} = Float.parse("100.0")

# 100.0
IO.inspect number 
1 Like
iex(1)> Integer.parse("100.0")
{100, ".0"}
iex(2)> {value, _} = Integer.parse("100.0")
{100, ".0"}
iex(3)> value
100
iex(4)> 

Integer.parse/2

1 Like

Given your other opened topic I’d also like to add the usual warning that you don’t want to use floats for money values. If you’re working with money it’s best to use a proper decimal or money datatype.

5 Likes

To expand on @LostKobrakai’s relevant comment: Decimal.

Don’t really want this either, rather you want something like:

50/50. I’ve used Decimal several times in very limited money calculations where no currencies were involved. But I agree, they money library is a better general fit.

Decimal is always the wrong choice for money I argue:

iex> d = Decimal.new("1.23")
#Decimal<1.23>
iex> Decimal.div(d, 2)
#Decimal<0.615>

And suddenly you have something that is not a valid money value. The Money library handles this properly.

1 Like
#Decimal<0.615>

Disagree. No, you can’t get 61.5 cents in change at the corner bodega, but the desired/required precision and rounding behavior in financial calculations is a business/domain decision.

1 Like

Another common practice is to use integers. See this stack overflow post. Stripe does this.

I’ve never used the elixir money library, but it looks interesting. Can anyone explain what the benefit would be to using the money library instead of integers? Or is it just a matter of preference?

Getting around floating point math (a.k.a. using integers) is just the tip of the iceberg in terms of properly handling money. There are different subdivisions of currencies, like ones, which cannot be subdevided or on the other hand e.g. bitcoin, which is commonly subdevided to 8 decimal places and it might need to get smaller in the future. Also I wouldn’t really suggest the money library in elixir, but rather ex_money, which is based in the cldr database, which not only has information about all those subdivisions, but also on things like formatting or rounding rules, which can even differ by type of transaction in some countries.

For a more complete list of what you can get wrong with money please read https://github.com/kipcole9/money#falsehoods-programmers-believe-about-prices

I’d guess stripe is using integers mostly because it makes it easy to interact with whatever other language or data transfer format they’ll need to interact with. It’s like the lowest common denominator of money handling.

5 Likes

Thank you, what a great response. I’ll be looking into this more.