Шаг 5.
Арифметические функции языка LISP

    На этом шаге мы перечислим основные арифметические функции языка LISP.

    Чтобы программировать с помощью функций, нужно иметь возможность определить достаточно богатое множество основных функций и затем использовать композицию, чтобы иметь возможность определить новые функции в терминах исходных. Возникает вопрос, нужно ли еще что-нибудь, кроме набора исходных функций и возможности составлять из них композиции для программирования. Наш ответ гласит, что ничего больше не требуется, и целью этого раздела является иллюстрация и подтверждение этой точки зрения.

    Для записи функций языка LISP применяется кэмбриджская польская нотация (вначале пишется имя функции, за которым идет последовательность ее аргументов), при этом скобки ставятся везде, где они должны присутствовать по смыслу. Тем самым удается получить простой и однородный синтаксис, но скобки часто делают структуры не очень наглядными.


    Замечание. Арифметические функции выполняют основные математические операции над целыми и дробными числами. В системе muLISP85 пользователь может выбрать для работы или точную, или приближенную рациональную арифметику. Для точной рациональной арифметики размер целых чисел, числителей и знаменателей ограничен приблизительно до   225000 десятичных знаков. Для приближенной рациональной арифметики (обычно ее называют - арифметикой с плавающей точкой) используемая точность также устанавливается в пределах этих ограничений.

    Если арифметическая функция, требующая целых аргументов, вызывается с нецелыми аргументами, то возникает прерывание по ошибке "Нецелый аргумент".

    Если арифметическая функция, требующая числовых аргументов, вызывается с нечисловыми аргументами, то взникает прерывание по ошибке "Нечисловой аргумент".

    Если числовая функция вызывается с недостаточным количеством аргументов, то возникает прерывание по ошибке "Недостаточное количество аргументов".

    Если сделана попытка деления на нуль, то возникает прерывание по ошибке "Деление на ноль".

    Как только возникло прерывание, на консоли высвечивается диагностическое сообщение, вызов функции и подсказка в виде опций прерывания. Прерывание позволяет пользователю определить причину ошибки и тип действий.

    Хотя дробные числа могут записываться либо в десятичном представлении, либо собственно в виде дроби (с помощью наклонной черты), во внутреннем представлении они хранятся как дробные числа, состоящие из двух целых.

    Отметим, что при вводе дробных чисел возле точки или наклонной черты пробелы не ставятся, а перед точкой должно стоять хотя бы одно десятичное число.

    Контрольные переменные *READ-BASE*, *PRINT-BASE* и *PRINT-POINT* задают способ представления чисел для ввода и вывода.


    В следующей таблице перечислены основные арифметические функции языка LISP диалекта muLISP85.

в
Таблица 1. Основные арифметические функции языка LISP
Функция
Назначение
(+ N1 N2 ... Nm)
Возвращает сумму чисел N1,...,Nm.
(- N1 N2 ... Nm)
Возвращает разность между N1 и суммой чисел N2,...,Nm.
(* N1 N2 ... Nm)
Возвращает произведение чисел N1,...,Nm.
(/ N1 N2 ... Nm)
Возвращает результат деления N1 на произведение чисел N2,...,Nm.
(MOD N M)
Возвращает результат деления N на M по модулю.
(GCD N1 N2 ... Nm)
Возвращает наибольший общий делитель чисел с N1 по Nm.
(LCM N1 N2 ... Nm)
Возвращает наименьшее общее кратное для чисел с N1 по Nm.
(NUMERATOR N)
Возвращает числитель числа N.
(DENOMINATOR N)
Возвращает знаменатель числа N.
(LOGAND N1 N2 ... Nm)
Возвращает результат выполнения побитового логического "И" над целыми числами N1,...,Nm.
(LOGIOR N1 N2 ... Nm)
Возвращает результат выполнения побитового логического "ИЛИ" над целыми числами N1, N2, ..., Nm.
(LOGXOR N1 N2 ... Nm)
Возвращает результат выполнения побитового логического исключающего "ИЛИ" (XOR) над целыми числами N1, N2, ..., Nm.
(LOGNOT N)
Возвращает результат выполнения побитового логического "НЕ" над числом N.
(SHIFT N M)
Возвращает результат сдвига N влево на M битов.
(BITLENGTH N)
Возвращает количество битов, требуемое для размещения числа N.
(MAX N1 N2 ... Nm)
Возвращает наибольший аргумент.
(MIN N1 N2 ... Nm)
Возвращает наименьший аргумент.
(ADD1 N)
Возвращает (+ N 1).
(SUB1 N)
Возвращает (- N 1).
(INCQ SYMBOL)
Увеличивает значение SYMBOL и возвращает новое значение.
(DECQ SYMBOL)
Уменьшает значение SYMBOL и возвращает новое значение.
(ABS N)
Возвращает абсолютное значение N.
(SIGNUM N)
Возвращает знак числа N.
(REM N M)
Возвращает остаток от деления N на M.
(DIVIDE N M)
Возвращает точечную пару, представляющую собой частное и остаток целочисленного деления N на M.
(PRECISION N)
Принимает N за значение точности и возвращает предыдущее значение точности.
(UNDERFLOW N)
Изменение значения точности вычислений.
(FLOOR ...)
"Усечение" значения по нижней границе.
(CEILING ...)
"Усечение" значения по верхней границе.
(TRUNCATE ...)
"Усечение" значения путем приближения его к нулю.
(ROUND ...)
Округление значения.
(QUOTE <аргумент>)
Запрещает вычисление значения своего аргумента и возвращает сам аргумент.

    1. Функция (+ N1 N2 ... Nm) возвращает сумму чисел N1,...,Nm. Если функция вызывается без аргументов, то она возвращает 0. Например:


   $ (+ 2 3 4)       $ (+ 0.25)
   9                 0.25
   $ (+ -5 3)        $ (+ 10 5 3)
   -2                18
   $ (+ 1/6 0.7)     $ (+)
   0.8666666         0
В начало таблицы

    2. Функция (- N1 N2 ... Nm) возвращает разность между N1 и суммой чисел N2,...,Nm. Функция (- N) возвращает -N. Если функция вызывается без аргументов, то возникает прерывание по ошибке "Недостаточное количество аргументов". Например:


   $ (- 12 5)        $ (- 17/9 1.5)
   7                 0.3888888
   $ (- 12 5 -3)     $ (- 8)
   10                -8
В начало таблицы

    3. Функция (* N1 N2 ... Nm) возвращает произведение чисел N1,...,Nm. Если функция вызывается без аргументов, то она возвращает 1. Например:


   $ (* 3 4 5)       $ (*)
   60                1
   $ (* 5/6 -0.7)    $ (* 2/5)
   -0.5833333        0.4
В начало таблицы

    4. Функция (/ N1 N2 ... Nm) возвращает результат деления N1 на произведение чисел с N2,...,Nm. Если функция вызывается с единственным аргументом, то она возвращает число, обратное аргументу. Если функция вызывается без аргументов, возникает прерывание по ошибке "Недостаточное количество аргументов". Если какой-либо аргумент, кроме первого, равен нулю, возникает прерывание по ошибке "Деление на нуль". Например:


   $ (/ 12 8)      $ (/ -4.7 1.3)
   1.5             -3.6153846
   $ (/ 12 5 -3)   $ (/ 5)
   -0.8            0.2
В начало таблицы

    5. Если N и M - числа, то функция (MOD N M) возвращает результат деления N на M по модулю. Например:


   $ (MOD 7 3)     $ (MOD 7 -3)
   1               -2
   $ (MOD -7 3)    $ (MOD -7 -3)
   2               -1

    Если M (делитель) равен нулю, возникает прерывание по ошибке "Деление на ноль".

    Заметим, что функция MOD определена так, что функции FLOOR и MOD сохраняют связь между частными и остатками: N = M * (FLOOR N M) + (MOD N M). Приведем код функции:


   (DEFINE MOD (N M)
      ( (AND (NUMBERP N) (NUMBERP M))
          ( (ZEROP M)
               (BREAK (LIST 'MOD N M) '"Zero Divide") )
          (- N (* M (FLOOR N M))) )
      ( BREAK (LIST 'MOD N M) '"Nonnumeric Argument" )
   )
Говоря языком математики, функция (MOD N1 N2) возвращает наименьший неотрицательный вычет числа N1 по модулю N2.

В начало таблицы

    6. Функция (GCD N1 N2 ... Nm) возвращает наибольший общий делитель чисел с N1 по Nm. Функция (GCD N) возвращает абсолютную величину числа N. Если функция вызывается без аргументов, то GCD возвращает 0.

    Функция GCD от двух чисел есть наибольшее неотрицательное целое число, которое одинаково делится на оба данных числа. GCD от двух дробных чисел есть GCD от числителей, деленный на LCM от знаменателей. Например:


   $ (GCD 12 -16 20)      $ (GCD 0 0)
   4                      0
   $ (GCD 14/15 8/9)      $ (GCD)
   0.0444444              0
   $ (GCD 0 5)            $ (GCD -7)
   5                      7
В начало таблицы

    7. Функция (LCM N1 N2 ... Nm) возвращает наименьшее общее кратное для чисел с N1 по Nm. Функция (LCM N) возвращает абсолютное значение N. Если функция LCM вызывается без аргументов, возникает прерывание по ошибке "Недостаточное количество аргументов". Функция LCM от двух целых чисел возвращает наименьшее целое, которое кратно обоим данным числам. Например:


   $ (LCM 12 -16 20)      $ (LCM 0 5)      $ (LCM -7)
   240                    0                7
   $ (LCM 14/15 8/9)      $ (LCM 0 0)
   18.6666666             0

    В общем случае функцию LCM от двух чисел N и M (целых или дробных) можно определить с помощью функции GCD как (/ (ABS (* N M)) (GCD N M)).

В начало таблицы

    8. Если число N - дробное, то функция (NUMERATOR N) возвращает числитель N. Если N - целое, то функция (NUMERATOR N) возвращает N. Числитель - это всегда целое число. Например:


   $ (NUMERATOR 10/8)    $ (NUMERATOR -8)
   5                     -8
   $ (NUMERATOR 0.75)
   3
В начало таблицы

    9. Если N - дробное число, функция (DENOMINATOR N) возвращает знаменатель числа N. Если N - целое, (DENOMINATOR N) возвращает 1. Знаменатель - это всегда положительное целое число. Например:


   $ (DENOMINATOR 10/8)   $ (DENOMINATOR -8)
   4                      1
   $ (DENOMINATOR 0.75)
   4
В начало таблицы

    Побитовые логические функции, рассматриваемые ниже, работают только с целыми числами. Если они вызываются с нецелыми аргументами, возникает прерывание по ошибке "Нецелый аргумент".

    10. Функция (LOGAND N1 N2 ... Nm) возвращает результат выполнения побитового логического "И" над целыми числами N1, ..., Nm. Если функция LOGAND вызывается без аргументов, то она возвращает -1. Например:


   $ (LOGAND 11 6)
   2
В начало таблицы

    11. Функция (LOGIOR N1 N2 ... Nm) возвращает результат выполнения побитового логического "ИЛИ" над целыми числами N1, N2, ..., Nm. Если функция LOGIOR вызывается без аргументов, то она возвращает 0. Например:


   $ (LOGIOR 11 6)
   15
В начало таблицы

    12. Функция (LOGXOR N1 N2 ... Nm) возвращает результат выполнения побитового логического исключающего "ИЛИ" (XOR) над целыми числами N1, N2, ..., Nm. Если функция LOGXOR вызывается без аргументов, то она возвращает 0. Например:


   $ (LOGXOR 11 6)
   13
В начало таблицы

    13. Функция (LOGNOT N) возвращает результат выполнения побитового логического "НЕ" над числом N. Например:


   $ (LOGNOT 9)
   65526
В начало таблицы

    14. Если M - положительное число, то функция (SHIFT N M) возвращает результат сдвига N влево на M битов. Если M - отрицательное число, то N "сдвигается" вправо на -M битов. Например:


   $ (SHIFT 5 2)     $ (SHIFT 5 -2)
   20                1
   $ (SHIFT 6 3)
   48    % 48=110000b
В начало таблицы

    15. Функция (BITLENGTH N) возвращает количество битов, требуемое для размещения числа N. Например:


   $ (BITLENGTH 4)   $ (BITLENGTH 8)
   3                 4
   $ (BITLENGTH 7)   $ (BITLENGTH 48)
   3                 6               % 48 = 110000b
В начало таблицы

    В файле COMMON.LSP системы muLISP85 определены следующие элементарные функции: EXP, EXPT, LOG, SQRT, ISQRT, SIN, COS, TAN, ASIN, ACOS, ATAN, PI, RANDOM.

    Напомним, что элементарными функциями называется класс функций, состоящий из степенных функций, многочленов, рациональных функций, показательных функций, логарифмических функций, тригонометрических функций, обратных тригонометрических функций, гиперболических функций, обратных гиперболических функций, а также функций, полученных из перечисленных выше с помощью четырех арифметических действий (сложения, вычитания, умножения и деления) и суперпозиций, применяемых конечное число раз.

    16. Функция (MAX N1 N2 ... Nm) возвращает свой наибольший аргумент. Например:


   $ (MAX 5 -7 4)    $ (MAX -4)
   5                 -4
   $ (MAX 2/3 0.6)
   0.6666666

    Если функция MAX вызывается без аргументов, то возникает прерывание по ошибке "Недостаточное количество аргументов". Код функции таков:


   (DEFUN MAX LST
      ( (NULL LST)
         ((BREAK (LIST 'MAX) '"Insufficient Arguments") )
      ( (NULL (CDR LST)) (CAR LST) )
      ((AND (NUMBERP (CAR LST)) (NUMBERP (CADR LST)))
         ( (< (CAR LST) (CADR LST))
             (APPLY 'MAX (CONS (CADR LST) (CDDR LST))) )
         (APPLY 'MAX (CONS (CAR LST) (CDDR LST))) )
      (APPLY 'MAX
             (CONS (BREAK (LIST 'MAX (CAR LST) (CADR LST))
                                  '"Nonnumeric Argument" )
                         (CDDR LST)))
   )
В начало таблицы

    17. Функция (MIN N1 N2 ... Nm) возвращает свой наименьший аргумент. Например:


   $ (MIN 5 -7 4)     $ (MIN -4)
   -7                 -4
   $ (MIN 2/3 0.6)
   0.6

    Если MIN вызывается без аргументов, возникает прерывание по ошибке "Недостаточное количество аргументов". Код функции таков:


   (DEFUN MIN LST
      ( (NULL LST)
          (BREAK (LIST 'MIN) '"Insufficient Arguments") )
      ( (NULL (CDR LST)) (CAR LST) )
      ((AND (NUMBERP (CAR LST)) (NUMBERP (CADR LST)))
          ((< CAR LST) (CADR LST))
             (APPLY 'MIN (CONS (CAR LST) (CDDR LST))) )
      (APPLY 'MIN (CONS (BREAK
                           (LIST 'MIN (CAR LST) (CADR LST))
                           '"Nonnumeric Argument" )
                     (CDDR LST)))
   )
В начало таблицы

    18. Функция (ADD1 N) возвращает (+ N 1). Например:


   $ (ADD1 3)    $ (ADD1 -3)
   4             -2
   $ (ADD 2/3)
   1.6666666

    Если ADD1 вызывается без аргументов, то возникает прерывание по ошибке "Недостаточное количество аргументов". Приведем код функции:


   (DEFUN ADD1 (N)
      ( (NUMBERP N) (+ N 1))
      ( BREAK (LIST 'ADD1 N) '"Nonnumeric Argument")
   )
В начало таблицы

    19. Функция (SUB1 N) возвращает (- N 1). Например:


   $ (SUB1 3)       $ (SUB1 -3)
   2                -4
   $ (SUB1 0.25)
   -0.75
Если функция SUB1 вызывается без аргументов, то возникает прерывание по ошибке "Недостаточное количество аргументов". Приведем код функции:

   (DEFUN SUB1 (N)
      ( (NUMBERP N) (- N 1) )
      ( BREAK (LIST 'SUB1 N) '"Nonnumeric Argument" )
   )
В начало таблицы

    20. Функция (INCQ SYMBOL) увеличивает значение SYMBOL и возвращает новое значение. Если N - число, то функция (INCQ SYMBOL N) прибавляет N к значению SYMBOL и возвращает новое значение. Например (SETQ - функция присваивания):


   $ (SETQ CTR 5)   $ (INCQ CTR 2)
   5                8
   $ (INCQ CTR)     $ CTR
   6                8
   $ CTR
   6

    Если SYMBOL не является символом muLISP, то функция генерирует прерывание по ошибке "Несимвольный аргумент".

В начало таблицы

    21. Функция (DECQ SYMBOL) уменьшает значение SYMBOL и возвращает новое значение. Если N - число, то функция (DECQ SYMBOL N) вычитает N из значения SYMBOL и возвращает новое значение. Например:


   $ (SETQ CTR 5)   $ (DECQ CTR 2)
   5                2
   $ (DECQ CTR)     $ CTR
   4                2
   $ CTR
   4

    Если SYMBOL не является символом muLISP, то функция DECQ генерирует прерывание по ошибке "Несимвольный аргумент".

В начало таблицы

    22. Если N - число, то функция (ABS N) возвращает абсолютное значение N. Например:


   $ (ABS 4/6)      $ (ABS 0)
   0.6666666        0
   $ (ABS -3)
   3
Код функции прост:

   (DEFUN ABS (N)
      ( (NUMBERP N) ( (MINUSP N) (- N) ) N )
      ( BREAK (LIST 'ABS N) '"Nonnumeric Argument" )
   )
В начало таблицы

    23. Если N - число, то функция (SIGNUM N) возвращает 1, -1 или 0 в зависимости от того, является ли N положительным, отрицательным или нулем. Например:


   $ (SIGNUM 7/2)
   1
   $ (SIGNUM 0)
   0
   $ (SIGNUM -0.2)
   -1
Приведем код функции:

   (DEFUN SIGNUM (N)
      ( (NUMBERP N) ((ZEROP N) 0) ((PLUSP N) 1) -1 )
      ( BREAK (LIST 'SIGNUM N) '"Nonnumeric Argument" )
   )
В начало таблицы

    24. Если N и M - числа, то функция (REM N M) возвращает остаток от деления N на M. Если M (делитель) равен нулю, то возникает прерывание по ошибке "Деление на ноль".

    Функция REM определена так, что функции TRUNCATE и REM сохраняют связь между частными и остатками: N = M * (TRUNCATE N M) + (REM N M). Например:


   $ (REM 7 3)      $ (REM 7 -3)
   1                1
   $ (REM -7 3)     $ (REM -7 -3)
   -1               -1
Приведем код функции:

   (DEFINE REM (N M)
      ( (AND (NUMBERP N) (NUMBERP M))
          ( (ZEROP M)
              (BREAK (LIST 'REM N M) '"Zero Divide") )
              (- N (* M (TRUNCATE N M))) )
      ( BREAK (LIST 'REM N M) '"Nonnumeric Argument" )
   )
В начало таблицы

    25. Если N - число, то функция (DIVIDE N) возвращает точечную пару, у которой CAR-элемент есть (TRUNCATE N), а CDR-элемент - (REM N).

    Если N и M - числа, то функция (DIVIDE N M) возвращает точечную пару, у которой CAR-элемент есть (TRUNCATE N M), а CDR-элемент - (REM N M).

    Если M (делитель) равен нулю, то возникает прерывание по ошибке "Деление на ноль".

    В том случае, когда требуются усеченные частное и остаток одновременно, выгоднее использовать функцию DIVIDE, чем вычислять их отдельно. Например:


   $ (DIVIDE 7 3)     $ (DIVIDE 7 -3)
   (2 . 1)            (-2 . 1)
   $ (DIVIDE -7 3)    $ (DIVIDE -7 -3)
   (-2 . -1)          (2 . -1)
Приведем код функции:

   (DEFINE DIVIDE (N M)
      ( (AND (NUMBERP N) (NUMBERP M))
          ( (ZEROP M)
              (BREAK (LIST 'DIVIDE N M) '"Zero Divide") )
          (CONS (TRUNCATE N M) (REM N M)) )
      ( BREAK (LIST 'DIVIDE N M) '"Nonnumeric Argument")
   )
В начало таблицы

    26. Если N - положительное целое, то функция (PRECISION N) принимает N за значение точности и возвращает предыдущее значение точности.

    Если N равно нулю, то функция (PRECISION N) принимает значение точности за бесконечность и возвращает предыдущее значение.

    Если N отсутствует или не является ни нулем, ни положительным целым, то функция (PRECISION N) возвращает текущее значение точности без его изменения.

    Если значение точности принято равным положительному целому N, то новое дробное число, сгенерированное числовыми функциями, автоматически округляется, если для размещения меньшей из величин его числителя и знаменателя требуется больше, чем N слов памяти (слово памяти состоит из 16 бит).

    Такое дробное число заменяется аппроксимацией, причем такой, которая требует для размещения наименьшей из величин числителя и знаменателя не более N слов.

    Первоначальное значение точности предполагается равным 1. Например:


   $ (PRECISION 0)
   1
   $ (PRECISION 5)
   0
   $ (PRECISION)
   5
   $ (PRECISION 1)
   5

    Так, функция PI, определенная в файле COMMON.LSP, в muLISP может апроксимироваться до любой желаемой степени точности. Ниже приведен пример вычисления PI до 100 знаков:


  $ (PROGN (PRECISION 10) (SETQ *PRINT-POINT* 100) (PI))
  3.14159265358979323846264338327950288419716939937510582097
  4445923078164062862089986280348253421173270
В начало таблицы

    27. Часто в процессе вычислений с аппроксимацией требуются такие числа, которые по абсолютной величине меньше, чем некоторое число с плавающей точкой, стремящееся к нулю (ситуация underflow).

    Если N - положительное целое, то функция (UNDERFLOW N) полагает значение, на котором возникает ситуация underflow, равным 65536 -N и возвращает предыдущее значение underflow.

    Если N - нуль, то функция (UNDERFLOW N) предотвращает возникновение underflow и возвращает предыдущее значение.

    Если N отсутствует или не является ни 0, ни положительным целым, то функция (UNDERFLOW N) возвращает текущее значение underflow без его изменения.

    Первоначально underflow принимается равным 7. Ниже приведена таблица 2 числовых значений underflow для различных значений N:

Таблица 1. Значения underflow для различных значений N
N
65536 -N
1
1.53*10 -5
2
2.33*10 -10
3
3.55*10 -15
4
5.42*10 -20
5
8.27*10 -25
6
1.26*10 -29
7
1.93*10 -34 (underflow по умолчанию)
8
2.94*10 -39
9
4.48*10 -44
10
6.84*10 -49

    Например:


   $ (UNDERFLOW 0)
   7
   $ (UNDERFLOW 5)
   0
   $ (UNDERFLOW)
   5
   $ (UNDERFLOW 7)
   5
В начало таблицы

    28. Если N - целое число, то функция (FLOOR N) возвращает N. Если N - дробное число, то функция FLOOR возвращает наибольшее целое число, меньшее N. Другими словами, функция FLOOR "усекает" N по нижней границе.

    Если N и M - числа, то функция (FLOOR N M) усекает по нижней границе частное от деления N на M. Функция (FLOOR N M) эквивалентна (FLOOR (/ N M)).

    Если N (делитель) - нуль, то возникает прерывание по ошибке "Деление на нуль". Например:


   $ (FLOOR 7.3)     $ (FLOOR 8 3)
   7                 2
   $ (FLOOR -3.5)    $ (FLOOR -15/4 2)
   -4                -2
В начало таблицы

    29. Если N - целое, то функция (CEILING N) возвращает N. Если N - дробное, то функция (CEILING N) возвращает наименьшее целое число, но больше, чем N. Другими словами, (CEILING N) "усекает" N по верхней границе.

    Если N и M - числа, то функция  (CEILING N M) усекает по верхней границе частное от деления N на M. Функция (CEILING N M) эквивалентна функции (CEILING (/ N M)).

    Если M (делитель) - нуль, то возникает прерывание по ошибке "Деление на нуль". Например:


   $ (CEILING 7.3)    $ (CEILING 8 3)
   8                  3
   $ (CEILING -3.5)   $ (CEILING -15/4 2)
   -3                 -1
В начало таблицы

    30. Если N - целое число, то функция (TRUNCATE N) возвращает N. Если N - положительное дробное число, то функция (TRUNCATE N) возвращает наибольшее целое число, но меньше N.

    Если N - отрицательное дробное число, то функция (TRUNCATE N) возвращает наименьшее целое число, но больше N. Другими словами, функция (TRUNCATE N) "усекает" N, приближая его к нулю.

    Если N и M - числа, то функция (TRUNCATE N M) "усекает" к нулю частное от деления N на M.

    Функция (TRUNCATE N M) эквивалентна функции (TRUNCATE (/ N M)).

    Если M (делитель) - нуль, то возникает прерывание по ошибке "Деление на нуль". Например:


   $ (TRUNCATE 7.3)    $ (TRUNCATE 8 3)
   7                   2
   $ (TRUNCATE -3.5)   $ (TRUNCATE -15/4 2)
   -3                  -1
В начало таблицы

    31. Если N - целое число, то функция (ROUND N) возвращает N. Если N - дробное, то функция (ROUND N) возвращает целое число, ближайшее по значению к N. Если N расположено "посередине" между двумя целыми числами (2*N - целое число), функция (ROUND N) возвращает одно из них, делящееся без остатка нк другое.

    Если N и M - числа, то функция (ROUND N M) округляет частное от деления N на M. Например:


   $ (ROUND 7.3)     $ (ROUND 8 3)
   7                 3
   $ (ROUND -3.5)    $ (ROUND -15/4 2)
   -4                -2

    Вызов (ROUND N M) эквивалентен (ROUND (/ N M)).

    Если M (делитель) - нуль, то возникает прерывание по ошибке "Деление на ноль".

В начало таблицы

    32. Функция QUOTE ("quote" [kwout] - "цитировать", "кавычки") запрещает вычисление значения своего аргумента и возвращает сам аргумент.

    Нас, например, может не интересовать значение функционального вызова (+ 1 2), равное 3, а мы хотим обрабатывать (+ 1 2) как список:


   $ (QUOTE (+ 1 2))
   (+ 1 2)
Приведем еще пару примеров:

   $ (QUOTE X)
   X
   $ (QUOTE (QUOTE 23))
   (QUOTE 23)

    К константам T, NIL и целым числам функцию QUOTE можно не применять, т.к. они представляют сами себя!

    Важно знать, что:

    Например:


   $ '(PLUS 1 2))   $ (CAR '(CONS 4 7))
   (PLUS 1 2)       CONS
Код функции QUOTE в muLISP85 имеет вид:

   (DEFUN QUOTE (NLAMBDA (OBJ)
      OBJ
   ))

    Отметим еще одну важную особенность интерпретатора muLISP: каждый новый литеральный атом по умолчанию имеет значение, совпадающее с "печатным" именем атома.

В начало таблицы

    На следующем шаге мы введем пронятие распознавателей.




Предыдущий шаг Содержание Следующий шаг