Числа с плавающей точкой
Функции для работы с числами с плавающей точкой.
Функции ядра
Функции, связанные с числами с плавающей точкой, также присутствуют в модуле Kernel. Вот список этих функций:
-
Kernel.round/1: округляет число до ближайшего целого. -
Kernel.trunc/1: возвращает целую часть числа.
Известные проблемы
Существуют некоторые хорошо известные проблемы с числами с плавающей точкой и арифметикой, обусловленные тем, что большинство десятичных дробей не могут быть точно представлены в двоичном формате чисел с плавающей точкой.
Например, числа 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 для получения более подробной информации об этих проблемах.
Резюме
Типы
- precision_range()
Функции
- 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)
Возвращает пару целых чисел, отношение которых точно равно исходному числу с плавающей точкой и с положительным знаменателем.
Примеры
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» by David M. Gay.
Примеры
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.6.6/Float.html