Число с плавающей точкой
Функции для работы с числами с плавающей точкой.
Функции ядра
Функции, связанные с числами с плавающей точкой, также доступны в модуле Kernel. Вот список этих функций:
-
Kernel.round/1: округляет число до ближайшего целого. -
Kernel.trunc/1: возвращает целую часть числа.
Известные проблемы
Существуют некоторые хорошо известные проблемы с числами с плавающей точкой и арифметикой, связанные с тем, что большинство десятичных дробей не могут быть точно представлены в двоичном формате с плавающей точкой, а большинство операций выполняются не точно, а приблизительно. Эти проблемы не специфичны для Elixir, они являются свойством самого представления чисел с плавающей точкой.
Например, числа 0.1 и 0.01 являются двумя из них, что означает, что результат возведения 0.1 в квадрат не даст ни 0.01, ни ближайшее представимое значение. Вот что происходит в этом случае:
- Ближайшее представимое число к 0.1 равно 0.1000000014
- Ближайшее представимое число к 0.01 равно 0.0099999997
- Вычисление 0.1 * 0.1 должно вернуть 0.01, но поскольку 0.1 фактически равно 0.1000000014, результат равен 0.010000000000000002, а поскольку это не ближайшее представимое число к 0.01, вы получите неправильный результат для этой операции.
Также существуют другие известные проблемы, такие как округление чисел вниз или округление вверх. См. round/2 и floor/2 для получения более подробной информации об этих проблемах.
Чтобы узнать больше о плавающей точке арифметике, посетите:
Краткое описание
Типы
Функции
- ceil(number, precision \\ 0)
Округляет число с плавающей точкой до наименьшего целого, большего или равного
num.- floor(number, precision \\ 0)
Округляет число с плавающей точкой до наибольшего числа, меньшего или равного
num.- parse(binary)
Парсит двоичное представление в число с плавающей точкой.
- ratio(float)
Возвращает пару целых чисел, отношение которых точно равно исходному числу с плавающей точкой, и с положительным знаменателем.
- round(float, precision \\ 0)
Округляет значение с плавающей точкой до произвольного числа знаков после запятой (от 0 до 15).
- to_charlist(float)
Возвращает список символов, который соответствует текстовому представлению данного числа с плавающей точкой.
- to_string(float)
Возвращает двоичное представление текстового представления данного числа с плавающей точкой.
Типы
precision_range()
Спецификации
precision_range() :: 0..15
Функции
ceil(number, precision \\ 0)
Спецификации
ceil(float(), precision_range()) :: float()
Округляет число с плавающей точкой до наименьшего целого, большего или равного num.
ceil/2 также принимает точность для округления значения с плавающей точкой вниз до произвольного числа знаков после запятой (от 0 до 15).
Операция выполняется над двоичным числом с плавающей точкой без преобразования в десятичное.
Поведение ceil/2 для чисел с плавающей точкой может быть неожиданным. Например:
iex> Float.ceil(-12.52, 2) -12.51
Можно было ожидать, что оно будет округлено до -12.52. Это не ошибка. Большинство десятичных дробей не могут быть представлены в двоичном формате с плавающей точкой, и поэтому указанное выше число в интерпретаторе представлено как -12.51999999, что объясняет указанное поведение.
Эта функция всегда возвращает числа с плавающей точкой. Kernel.trunc/1 можно использовать вместо этого для усечения результата до целого числа.
Примеры
iex> Float.ceil(34.25) 35.0 iex> Float.ceil(-56.5) -56.0 iex> Float.ceil(34.251, 2) 34.26
floor(number, precision \\ 0)
Спецификации
floor(float(), precision_range()) :: float()
Округляет число с плавающей точкой до наибольшего числа, меньшего или равного num.
floor/2 также принимает точность для округления значения с плавающей точкой вниз до произвольного числа знаков после запятой (от 0 до 15). Операция выполняется над двоичным числом с плавающей точкой без преобразования в десятичное.
Эта функция всегда возвращает число с плавающей точкой. Kernel.trunc/1 можно использовать вместо этого для усечения результата до целого числа.
Известные проблемы
Поведение floor/2 для чисел с плавающей точкой может быть неожиданным. Например:
iex> Float.floor(12.52, 2) 12.51
Можно было ожидать, что оно будет округлено до 12.52. Это не ошибка. Большинство десятичных дробей не могут быть представлены в двоичном формате с плавающей точкой, и поэтому указанное выше число в интерпретаторе представлено как 12.51999999, что объясняет указанное поведение.
Примеры
iex> Float.floor(34.25) 34.0 iex> Float.floor(-56.5) -57.0 iex> Float.floor(34.259, 2) 34.25
parse(binary)
Спецификации
parse(binary()) :: {float(), binary()} | :error Парсит двоичное представление в число с плавающей точкой.
При успехе возвращает кортеж в формате {float, remainder_of_binary}; если двоичное представление не может быть преобразовано в действительное число с плавающей точкой, возвращается атом :error.
Если размер числа с плавающей точкой превышает максимальный размер 1.7976931348623157e+308, генерируется исключение ArgumentError.
Если вы хотите преобразовать строковое представление числа с плавающей точкой непосредственно в число с плавающей точкой, можно использовать String.to_float/1.
Примеры
iex> Float.parse("34")
{34.0, ""}
iex> Float.parse("34.25")
{34.25, ""}
iex> Float.parse("56.5xyz")
{56.5, "xyz"}
iex> Float.parse("pi")
:error ratio(float)
Спецификации
ratio(float()) :: {integer(), pos_integer()} Возвращает пару целых чисел, отношение которых точно равно исходному числу с плавающей точкой, и с положительным знаменателем.
Примеры
iex> Float.ratio(0.0)
{0, 1}
iex> Float.ratio(3.14)
{7070651414971679, 2251799813685248}
iex> Float.ratio(-3.14)
{-7070651414971679, 2251799813685248}
iex> Float.ratio(1.5)
{3, 2}
iex> Float.ratio(-1.5)
{-3, 2}
iex> Float.ratio(16.0)
{16, 1}
iex> Float.ratio(-16.0)
{-16, 1} round(float, precision \\ 0)
Спецификации
round(float(), precision_range()) :: float()
Округляет значение с плавающей точкой до произвольного числа знаков после запятой (от 0 до 15).
Направление округления всегда соответствует правилу округления до ближайшего, при равенстве округляется в большую сторону. Операция выполняется над двоичным числом с плавающей точкой без преобразования в десятичное.
Эта функция принимает только числа с плавающей точкой и всегда возвращает число с плавающей точкой. Используйте Kernel.round/1, если вам нужна функция, принимающая как числа с плавающей точкой, так и целые числа и всегда возвращающая целое число.
Известные проблемы
Поведение round/2 для чисел с плавающей точкой может быть неожиданным. Например:
iex> Float.round(5.5675, 3) 5.567
Можно было ожидать, что оно будет округлено до 5.568 при округлении вверх. Это не ошибка. Большинство десятичных дробей не могут быть представлены в двоичном формате с плавающей точкой, и поэтому указанное выше число в интерпретаторе представлено как 5.567499999, что объясняет указанное поведение. Если вам необходимо точное округление для десятичных дробей, используйте библиотеку для работы с десятичными числами. Указанное выше поведение также соответствует эталонным реализациям, таким как «Правильное округление двоично-десятичных и десятично-двоичных преобразований» Дэвида М. Гея.
Примеры
iex> Float.round(12.5) 13.0 iex> Float.round(5.5674, 3) 5.567 iex> Float.round(5.5675, 3) 5.567 iex> Float.round(-5.5674, 3) -5.567 iex> Float.round(-5.5675) -6.0 iex> Float.round(12.341444444444441, 15) 12.341444444444441
to_charlist(float)
Спецификации
to_charlist(float()) :: charlist()
Возвращает список символов, который соответствует текстовому представлению данного числа с плавающей точкой.
Используется кратчайшее представление в соответствии с алгоритмом, описанным в «Быстрое и точное вычисление чисел с плавающей точкой» в Трудах конференции SIGPLAN '96 по проектированию и реализации языков программирования.
Примеры
iex> Float.to_charlist(7.0) '7.0'
to_string(float)
Спецификации
to_string(float()) :: String.t()
Возвращает двоичное представление текстового представления данного числа с плавающей точкой.
Используется кратчайшее представление в соответствии с алгоритмом, описанным в «Быстрое и точное вычисление чисел с плавающей точкой» в Трудах конференции SIGPLAN '96 по проектированию и реализации языков программирования.
Примеры
iex> Float.to_string(7.0) "7.0"
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.10.4/Float.html