Числа с плавающей точкой
Функции для работы с числами с плавающей точкой.
Функции ядра
Функции, связанные с числами с плавающей точкой, также есть на модуле 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, что объясняет поведение выше. Если вам нужно точное округление для десятичных чисел, используйте библиотеку десятичных чисел. Приведенное выше поведение также соответствует эталонным реализациям, таким как «Correctly Rounded Binary-Decimal and Decimal-Binary Conversions» Дэвида М. Гейя.
Примеры
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()
Возвращает список символов, соответствующий текстовому представлению заданного числа с плавающей точкой.
Использует самое короткое представление в соответствии с алгоритмом, описанным в «Printing Floating-Point Numbers Quickly and Accurately» в «Proceedings of the SIGPLAN '96 Conference on Programming Language Design and Implementation».
Примеры
iex> Float.to_charlist(7.0) '7.0'
to_string(float)
Спецификации
to_string(float()) :: String.t()
Возвращает двоичную строку, соответствующую текстовому представлению заданного числа с плавающей точкой.
Использует самое короткое представление в соответствии с алгоритмом, описанным в «Printing Floating-Point Numbers Quickly and Accurately» в «Proceedings of the SIGPLAN '96 Conference on Programming Language Design and Implementation».
Примеры
iex> Float.to_string(7.0) "7.0"
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.9.4/Float.html