Тогда как большинство арифметических функций будут оперировать любым типом чисел, выполняя при необходимости приведения, следующие функции позволяют явно преобразовывать типы данных.
Преобразует любое некомплексное число в число с плавающей точкой. При отсутствии необязательного параметра, если number уже является числом с плавающей точкой, то оно и будет возвращено, иначе число будет преобразовано в single-float. Если аргумент other указан, тогда он должен быть числом с плавающей точкой, и number будет конвертирован в такой же формат как у other.
Смотрите также coerce.
Каждая из этих функций преобразует любое некомплексное число в рациональное. Если аргумент уже является рациональным, он возвращается как есть. Две функции различаются в том, как они обрабатывают числа с плавающей точкой.
rational предполагает, что число с плавающей точкой совершенно точно, и возвращает рациональное число математически эквивалентное значению числа с плавающей точкой.
rationalize предполагает, что число с плавающей точкой приближенное, и может возвращать любое рациональное число, для которого исходное число является наилучшим приближением. Функция пытается сохранить числитель и знаменатель наименьшими насколько это возможно.
Следующие тождества всегда справедливы
и
То есть, преобразование числа с плавающей точкой любым из методов туда и обратно даёт исходное число. Различие в том, что rational обычно имеет более простую недорогую реализацию, тогда как rationalize представляет более «красивое» число.
Эти функции принимают рациональное число (целое или дробное) и возвращают в качестве целого числа числитель или знаменатель дроби, приведённое к каноническому виду. Числитель целого числа и является этим числом. Знаменатель целого числа 1. Следует отметить, что
Знаменатель будет всегда строго положительным числом. Числитель может быть любым целым числом. Например:
В Common Lisp’е нет функции fix, потому что есть несколько интересных способов преобразовать нецелое число к целому. Эти способы представлены функциями ниже, которые выполняются не только преобразование типа, но также некоторые нетривиальные вычисления.
[Функция]
floor number &optional divisorПри вызове с одним аргументом, каждая из этих функций преобразует аргумент number (который не может быть комплексным числом) в целое число. Если аргумент уже является целым числом, то он немедленно возвращается в качестве результата. Если аргумент дробь или число с плавающей точкой, для конвертации функции используют различные алгоритмы.
floor преобразовывает аргумент путём отсечения к отрицательной бесконечности, то есть, результатом является наибольшее целое число, которое не больше чем аргумент.
ceiling преобразовывает аргумент путём отсечения к положительной бесконечности, то есть, результатом является наименьшее целое число, которое не меньше чем аргумент.
truncate преобразовывает аргумент путём отсечения к нулю, то есть, результатом является целое число с таким же знаком, которое имеет наибольшую целую величину, но не большую чем аргумент.
round преобразовывает аргумент путём округление к ближайщему целому. Если исходное число находится посередене (то есть содержит слагаемое + 0.5), тогда оно округляется к ближайщему чётному числу (которое делится на два).
Следующая таблица содержит то, что возвращают четыре функции для разных аргументов.
Аргумент | floor | ceiling | truncate | round |
2.6 | 2 | 3 | 2 | 3 |
2.5 | 2 | 3 | 2 | 2 |
2.4 | 2 | 3 | 2 | 2 |
0.7 | 0 | 1 | 0 | 1 |
0.3 | 0 | 1 | 0 | 0 |
-0.3 | -1 | 0 | 0 | 0 |
-0.7 | -1 | 0 | 0 | -1 |
-2.4 | -3 | -2 | -2 | -2 |
-2.5 | -3 | -2 | -2 | -2 |
-2.6 | -3 | -2 | -2 | -3 |
Если указан второй аргумент divisor, тогда аргумент number будет разделен на divisor, а затем уже будут проведены вышеописанные действия. Например, (floor 5 2) ≡ (values (floor (/ 5 2))), но первый вариант потенциально эффективнее.
This statement is not entirely accurate; one should instead say that (values (floor 5 2)) ≡ (values (floor (/ 5 2))), because there is a second value to consider, as discussed below. In other words, the first values returned by the two forms will be the same, but in general the second values will differ. Indeed, we have
for this example.
divisor
может любым числом, кроме комплексного. divisor не может равняться нулю. Случай вызова функции с одним аргументом эквивалентен вызову с двумя аргументами, последний из которых равен 1.In other words, the one-argument case returns an integer and fractional part for the number: (truncate 5.3) ⇒ 5.0 and 0.3, for example.
Каждая из функций возвращает два значения. Второе значение является остатком и может быть получено с помощью multiple-value-bind или другими подобными конструкциями. Если любая из этих функций получает два аргумента x и y и возвращает q и r, тогда q ⋅y + r = x. Первое значение результата q всегда целочисленное. Остаток r целочисленный, если оба аргумента были целочисленными, и рациональное, если оба аргумента были рациональными, и с плавающей точкой, если один из аргументов был с плавающей точкой. Если при вызове был указан один аргумент, то тип данных остатка всегда такой же как и этот аргумент.
Когда указывается только один аргумент, сумма двух значений результата точно равняется переданному в параметре значению.
mod выполняет операцию floor для двух аргументов и возвращает второй результат floor. Таким же образом, rem выполняет операцию truncate для двух аргументов и возвращает второй результат truncate.
Таким образом mod и rem являются обычными функциями вычисления остатка от деления двух чисел. Аргументы могут быть также числами с плавающей точкой.
[Функция]
ffloor number &optional divisorЭти функции похожи на floor, ceiling, truncate и round за исключением того, что результат (первый из двух) всегда целое число, а не число с плавающей точкой. Это примерно, как если бы ffloor передала аргументы в floor, а затем применила к первому результату float и вернула полученную пару значений. Однако, на практике ffloor может быть реализована более эффективно. Такое же описание подходит к остальным трём функциям. Если первый аргумент является числом с плавающей точкой, и второй аргумент не точнее типа первого, тогда первый результат будет такого же типа как первый аргумент. Например:
[Функция]
decode-float floatФункция decode-float принимает числа с плавающей точкой и возвращает три значения.
Первое значение является мантиссой и числом того же типа, что и аргумент. Второе значение является целочисленной экспонентой. Третье значение отображает знак аргумента (-1.0 или 1.0) и является и числом того же типа, что и аргумент . Пусть b есть система счисления для отображения чисел с плавающей точкой, тогда decode-float делит аргумент на b в некоторой степени, чтобы привести значение в промежуток включая 1/b и не включая 1 и возвращает частное в качестве первого значения FIXME. Однако, если аргумент равен нулю результат равен абсолютному значению аргумента (то есть, если существует отрицательный ноль, то для него возвращается положительный ноль).
Второе значение decode-float является целочисленным экспонентой e, которая равняется степени, в которую было возведено b. Если аргумент равен нулю, то может быть возвращено любое целое число, при условии, что тожество, описанное ниже для scale-format, имеет место быть.
Третье значение decode-float является числом с плавающей точкой в том же формате, что и аргумент, абсолютное значение которого равно 1, и знак совпадает со знаком аргумента.
Функция scale-float принимает число с плавающей точкой f (не обязательно между 1/b и 1) и целое число k, и возвращает (* f (expt (float b f ) k)). (Использование scale-float может быть более эффективным, чем использование возведения в степень или умножения и позволяет избежать переполнений).
Следует отметить, что
и
Функция float-radix возвращает (в качестве целого числа) основание b для числа с плавающей точкой.
Функция float-sign возвращает такое число с плавающей точкой z, что z и float1 имеют одинаковый знак, и z и float2 имеют равное абсолютное значение. Аргумент float2 по-умолчанию имеет значение (float 1