У меня есть внешний API, который возвращает числа в виде строк в следующем формате
5e+24
что должно означать число, равное 5 * 10^24
==> 5 с 24 нулями.
Есть ли у Эликсира возможность конвертировать такие числа в целые?
И как этот формат вообще называется?
Так же, если вопрос не про эрланг, не стоит его так помечать.
Вам дали несколько хороших ответов на ваш вопрос. Если есть дополнительные вопросы, вы должны открыть новые вопросы, а не добавлять дополнительные вопросы через комментарии. Или, по крайней мере, отредактируйте исходный вопрос, включив в него дополнения.
Это иногда называют научной нотацией или нотацией E.
Эти числа можно преобразовать из строки в число с плавающей запятой в Elixir с помощью Float.parse
:
iex> Float.parse "3.1e+4"
{31000.0, ""}
iex> Float.parse "5e+24"
{5.0e24, ""}
Как вы можете видеть в последнем примере, он возвращает число в нотации E, но это все еще число с плавающей запятой, с которым вы можете работать.
Остерегайтесь всех ловушек, которые есть у плавающего типа. Если, например, вы попытаетесь получить красивое строковое представление этого числа, могут произойти странные вещи:
{number, _} = Float.parse("5e+24")
Float.to_string number
# "5.0e24"
:erlang.float_to_binary number
# "5.00000000000000045298e+24"
:erlang.float_to_binary number, decimals: 0
"5000000000000000452984832"
Вопрос в том, как сделать из него 5 с 24 нулями.
В конце концов, мне нужно это число как целое число. Как бы я преобразовал 5.0e24
в один?
Ваш вопрос был: как называется эта запись и как мне разобрать ее на число.
5000000000000000000000000 == 5.0e24
==> ложь
Да, я пробовал эти способы преобразовать его в целое число, а также trunc(..)
, floor(..)
. Однако ни один из них не преобразовал число с плавающей запятой в правильное целое число, которое равно 500000...(24 zeros)
Вы можете разделить строку и умножить ее самостоятельно:
[a, b] = String.split("5e+24", "e+")
String.to_integer(a) * 10 ** String.to_integer(b)
Но это не обычный способ сделать это, это хак. Что, если бы однажды вернули "5e24" без +?
Вы не спросили об этом в своем вопросе. Что делать, если вы получили 5.678e2
? Вам нужно задать более точный вопрос.
Если это будет возвращено, ваше решение тоже не сработает. Вы предложили хак, т.е.
Это не лайфхак, это ответ на заданный вами вопрос. Проблема в том, что вы, похоже, не просили того, чего на самом деле хотите. Я попросил разъяснений выше.
Ответ zwippie касается поплавков, но, как он упоминает, у поплавков есть некоторые проблемы. Если вам нужно чисто целочисленное решение, я не нашел существующего способа разобрать строку в экспоненциальном представлении в целое число Эликсира. Вы должны сами проанализировать целое число, например, что-то вроде:
defmodule BigInteger do
def parse(s) do
{i, e} = Integer.parse(s)
e = String.downcase(e)
if not String.starts_with?(e, "e") do
{:error, "No \"e\""}
else
e = String.slice(e, 1..-1)
cond do
String.starts_with?(e, "+") ->
{exp, rest} = Integer.parse(String.slice(e, 1..-1))
if rest != "" do
IO.inspect(rest)
{:error, "Not integer after \"e+\""}
else
{:ok, i * Integer.pow(10, exp)}
end
True ->
{exp, rest} = Integer.parse(String.slice(e, 0..-1))
if rest != "" do
{:error, "Not integer after \"e\""}
else
{:ok, i * Integer.pow(10, exp)}
end
end
end
end
end
IO.inspect(BigInteger.parse("3e+24"))
IO.inspect(BigInteger.parse("4e24"))
IO.inspect(BigInteger.parse("5E24"))
Для этого можно использовать пакет Number.
Он принимает строки и числа с плавающей запятой:
Number.Delimit.number_to_delimited("5e+24")
дает:
"5,000,000,000,000,000,000,000,000.00"
Если вам не нужны запятые:
Number.Delimit.number_to_delimited("5e+24", delimiter: "")
Урожайность:
"5000000000000000000000000.00"
Если вы не хотите ничего после десятичной точки:
Number.Delimit.number_to_delimited("5e+24", delimiter: "", precision: 0)
дает:
"5000000000000000000000000"
Вы вернули мои правки к своему вопросу, в котором поясняется, что вы запрашиваете целое число на основе ваших ответов на zwippie:
5000000000000000000000000 == 5.0e24
может быть истинным только для целых чисел. Уточните, пожалуйста, что вы имеете в виду под словом «десятичный». В нынешнем виде вопрос недостаточно конкретен.