1

This is how I'm doing it in Python... Is there a more elegant way to do it in Elixir?

def get_digits_past_decimal(number):
    number_string = str(number)
    dig_past_decimal = abs(Decimal(number_string).as_tuple().exponent)
    return dig_past_decimal
Afshin Moazami
  • 2,092
  • 5
  • 33
  • 55
Emily
  • 2,129
  • 3
  • 18
  • 43

1 Answers1

3

I'd convert the float to a string and count the number of bytes after the dot:

One Liner:

float |> Float.to_string |> String.split(".") |> Enum.at(1) |> byte_size

Slightly longer but more efficient as it doesn't create an intermediary list:

string = float |> Float.to_string
{start, _} = :binary.match(string, ".")
byte_size(string) - start - 1

Test:

defmodule A do
  def count1(float) do
    float |> Float.to_string |> String.split(".") |> Enum.at(1) |> byte_size
  end

  def count2(float) do
    string = float |> Float.to_string
    {start, _} = :binary.match(string, ".")
    byte_size(string) - start - 1
  end
end

for f <- [0.1, 0.234, 123.456, 0.0000000001] do
  IO.inspect {A.count1(f), A.count2(f)}
end

Output:

{1, 1}
{3, 3}
{3, 3}
{5, 5}

Note: the results may not be identical to Python since there are multiple ways to convert a float to a decimal string with slightly different outputs and tradeoffs. This question has some more information about this.

Community
  • 1
  • 1
Dogbert
  • 212,659
  • 41
  • 396
  • 397