Common Lisp/Числові функції

Матеріал з Вікіпідручника

Числові функції[ред.]

Числові функції виконують основні математичні операції над цілими та дробовими числами. Користувач може обрати для роботи точну або наближену раціональну арифметику. Для точної раціональної арифметики розмір цілих чисел, чисельників та знаменників обмежений приблизно до 25000 десяткових знаків.

Примітивними числовими функціями є додавання, віднімання, множення та ділення. В мові програмування Лісп вони є n-арними, тобто кількість їхніх аргументів необмежена. Синтаксис числових функцій наступний:

  1. (+ num1 num2 ... numM)
  2. (- num1 num2 ... numM)
  3. (* num1 num2 ... numM)
  4. (/ num1 num2 ... numM)

Функція додавання повертає суму своїх аргументів. Функція віднімання повертає різницю першого аргумента та суми всіх інших аргументів. Функція множення повертає добуток своїх аргументів. Функція ділення повертає частку від ділення першого аргумента та добутку інших аргументів.

$ (+ 2 4 6 7)
19

$ (- 20 3 5 6)
6

$ (* 2 4 6)
48

$ (/ 24 2 2 3)
2

Функції збільшення та зменшення мають наступний синтаксичний вигляд:CL(−)

1. (ADD1 <n>). Повертає значення, яке на одиницю більше за аргумент.

2. (SUB1 <n>). Повертає значення, яке на одиницю менше за аргумент.

3. (INCQ <sym><n>) Збільшує значення символа <sym> на число <n>.

4. (DECQ <sym><n>) Зменшує значення символа <sym> на число <n>.

Якщо функцію додавання (віднімання) одиниці запустити без аргументів, то виникне переривання по помилці: недостатня кількість аргументів. Якщо у функцію INCQ або DECQ передати один аргумент - символ, то збільшення (зменшення) значення символа відбудеться на одиницю. Окрім того, що функції INCQ та DECQ повертають результат арифметичної дії, значення символів, які передаються до них як аргументи, змінюється. CL(−) $ (ADD1 6) 7

$ (SUB1 10) 9

$ (SETQ S 10)$ (INCQ S 14)$ (DECQ S 4)

102430

Функції MIN та MAX повертають символ з відповідно мінімальним (максимальним) значенням.

  1. (MIN n1 n2 ... nM)
  2. (MAX n1 n3 ... nM)
$ (MIN 12 3 45 67)
3

$ (MAX 1 2 5 3)
5

Числові вирази в Ліспі записуються в префіксній формі. Вираз 3*5+5*7 для обчислення треба подати у вигляді (+ (* 3 5) (* 5 7)), вираз (3+6)*7 — у вигляді (* (+ 3 6) 7).

Функції порівняння менше та більше мають n аргументів.

  1. (< n1 n2 ... nM) Повертає істину, якщо n1 < n2 < ... < nM.
  2. (> n1 n2 ... nM) Повертає істину, якщо n1 > n2 > ... > nM
  3. (/= n1 n2 ... nM) Повертає істину, якщо існують хоча б два числа, які не дорівнюють одне одному.

До функцій порівняння також відносяться <= , = та >=.

$ (< 2 4 6)
T

$ (>= 5 3 3 2)
T

$ (/= 4 4 5)
T

$ (< 6 6 8 15)
NIL

$ (<= 6 6 8 15)
T

$ (/= 4 4 4)
NIL

Функції округлення[ред.]

  • (TRUNCATE m n)
  • (ROUND m n)
  • (CEILING m n)
  • (FLOOR m n)

Ці функції використовуються для округлення дробових чисел до цілих. TRUNCATE виконує округлення до ближчого цілого у напрямку нуля. ROUND виконує округлення до ближчого цілого по значенню до m/n. CEILING виконує округлення до ближнього цілого по верхній межі, FLOOR — по нижній межі. Виклик будь-якої функції з двома аргументами (f m n) еквівалентний виклику функції з одним аргументом: (f (/ n m)), де f — будь-яка з наведених чотирьох функцій.

$ (TRUNCATE 6/4)
1

$ (TRUNCATE -6/4)
-1

$ (CEILING 9 4)
3

$ (CEILING -9 4)
-2

$ (FLOOR 6 4)
1

$ (FLOOR -6 4)
-2

$ (FLOOR 6/4)
1

$ (FLOOR -6/4)
-2

Функції остачі[ред.]

(REM m n), (MOD m n), (DIVIDE m n)

Примітивна функція REM повертає остачу від ділення числа m на n. Функція MOD працює як REM, але повертає модуль остачі. Якщо (TRUNCATE m n) повертає q, а (REM m n) повертає r, то m=q*n+r. Функція (DIVIDE m n) повертає конс, CAR якого дорівнює частці, а CDR — остачі від ділення m на n.

$ (REM 6 4)$ (DIVIDE 7 2)$ (REM -6 4)$ (MOD 6 4)

2(3 . 1)-22


Знак числа[ред.]

  • (SIGNUM n)

Повертає значення -1, 0 або 1 якщо n відповідно від’ємне, 0, або додатнє.


Модуль числа[ред.]

  • (ABS n)

Повертає модуль (абсолютне значення) числа n.


Чисельник та знаменник[ред.]

(NUMERATOR n), (DENOMINATOR n) – чисельник та знаменник числа n.

$ (signum -5/3)$ (abs -5/3)$ (numerator 10/8)$ (denominator 10/8 )

-15/354


Побітові логічні функції[ред.]

(LOGAND <n1><n2>...<nM>), (LOGIOR <n1><n2>...<nM>), (LOGXOR <n1><n2>...<nM>), (LOGNOT n).

$ (LOGAND 5 7 3)$ (LOGIOR 4 2 1)$ (LOGXOR 5 2 3) $ (LOGNOT 6)

174 -7

Булеві функції[ред.]

(NOT <об’єкт>), (AND <форма1> <форма2> ... <формаN>), (OR <форма1> <форма2> ... <формаN).

$ (AND (EQL ‘as ‘as) (< 2 4))$ (OR NIL (< 4 56))$ (NOT (EQL ‘d ‘g))

TTT

Зсув[ред.]

CL(−) (SHIFT m n) — зсув числа m на n бітів.

$ (SHIFT 3 1)$ (SHIFT 3 -1)$ (GCD 24 66 600)$ (LCM 24 66 600)

6166600

НСД, НСК[ред.]

(GCD n1 n2 ... nM), (LCM n1 n2 ... nM). Ці функції знаходять відповідно найбільший спільний дільник M чисел та найменше спільне кратне.

В Коммон Ліспі визначено набір ірраціональних та трансцендентних функцій. Аргументи тригонометричних функцій задаються в радіанах.

  1. (EXP x)
    експонента ex
  2. (EXPT x y)
    степінь xy
  3. (LOG x y)
    логарифм logyx. Якщо y не задано, основа вважається рівною e.
  4. (LN x) CL(−)
    натуральний логарифм
  5. (SQRT x)
    квадратний корінь
  6. (ISQRT x)
    ціла частина з квадратного кореня
  7. (SIN x) та (ASIN x)
    сінус та арксінус
  8. (COS x) та (ACOS x)
    косинус та арккосинус
  9. (TAN x) та (ATAN x)
    тангенс та арктангенс
  10. (RANDOM n)
    генерується натуральне число, менше за n.


Задача 1. Список lst має 100 елементів, які дорівнюють 0 або 1. Написати функцію (CHANGE01 lst), яка повертає список, у якому всі елементи 0 замінені на 1, а 1 – на 0.

Необхідно замість використання умовного оператора застосувати дію x := 1−x.CL(+)

(DEFUN CHANGE01 (lst)
  (if (NULL lst) NIL
    (CONS (- 1 (CAR lst)) (CHANGE01 (CDR lst)))))

Задача 2. Змінним a та b присвоєні числа. Записати функцію в одному рядку (не визначати цю функцію), в результаті якої змінні обмінюються своїми значеннями. Використовувати допоміжні змінні забороняється.CL(+)

$ (SETQ a 2 b 3) ;; a = 2, b = 3
$ (SETQ a (+ a b) b (- a b) a (- a b))  ;; a = 3, b = 2

Задача 3. Відомо, що lst – список, який містить неспадну послідовність чисел. Функція (NUM lst) повинна обчислювати кількість різних чисел у ньому.CL(−) невірний алгоритм

(DEFUN NUM (lst)
  (if (null (CDR lst))
      1
      (if (/= (CAR lst) (CADR lst))
	  (+ 1 (NUM (CDR lst)))
	(NUM (CDR lst)))))

Задача 4. Списки lst1 та lst2 містять строго зростаючі послідовності чисел. Знайти кількість спільних елементів у цих масивах. Часова оцінка алгоритму повинна дорівнювати O(K+L), де K та L — довжини списків lst1 та lst2 відповідно.CL(+)

(defun comelement (lst1 lst2)
  (cond
   ((or (NULL lst1) (NULL lst2))
    0)
  ((< (CAR lst1) (CAR lst2))
   (COMELEMENT (CDR lst1) lst2))
  ((> (CAR lst1) (CAR lst2))
   (COMELEMENT lst1 (CDR lst2)))
  (t
   (+ 1 (COMELEMENT (CDR lst1) (CDR lst2))))))