Скалярными значениями (скалярами) в Athanor называются числа и строки. Это – простейшие типы данных из всех доступных в языке. Общее свойство всех скаляров – их неизменяемость (иммутабельность). Говоря проще, сами числа и строки изменять нельзя (но можно создавать и присваивать новые).
Простейший вид числовых значений – литералы. Их синтаксис, в общем, типичен для большинства языков программирования. Вот некоторые примеры допустимых числовых литералов:
Первые два литерала – целые, остальные – плавающие. Целочисленные литералы в тексте программы могут задаваться не только в десятичной форме. Если перед литералом стоит префикс '\x' – литерал шестнадцатиричный; префикс '\o' – он восьмеричный; префикс '\b' – он двоичный.
Скалярные операции, как правило, имеют операндами один или два скалярных значения, и возвращают скаляр в качестве результата. Каждая из операций имеет или операторную (синтаксическую, более удобную и привычную глазу) форму, или же (внутреннюю) функциональную форму. По типу своих операндов – эти операции можно разделить на числовые и строковые.
Кроме того, все операции языка (они же функторы) можно классифицировать по количеству операндов (их арности): они могут быть с одним операндом (унарные), с двумя операндами (бинарные), с тремя операндами (тернарные), вообще не иметь операндов (нульарные) или иметь их произвольное количество (таких тоже есть довольно много).
Вот основные бинарные скалярные операции для числовых операндов:
|
A + B
|
add (A,B)
|
сумма A и B
|
|
A - B
|
sub (A,B)
|
разность A и B
|
|
A * B
|
mul (A,B)
|
произведение A и B
|
|
A / B
|
div (A,B)
|
частное A и B
|
|
A % B
|
idiv (A,B)
|
целочисленное деление A на B
|
|
A %% B
|
irem (A,B)
|
остаток от целого деления A на B
|
А вот важнейшие унарные скалярные операции:
|
- A
|
neg (A)
|
арифметическое отрицание A
|
|
+ A
|
abs (A)
|
абсолютная величина (модуль) A
|
|
~ A
|
not (A)
|
битовое дополнение A
(битовое «НЕ»)
|
В языке также определены отдельные специальные операции для максимума и минимума из двух операндов:
|
A ?< B
|
min (A,B)
|
меньшее из значений A и B
|
|
A ?> B
|
max (A,B)
|
большее из значений A и B
|
Для целых чисел также определены операции сравнения, побитовые логические операции и сдвиги:
|
A & B
|
and (A,B)
|
битовое «И» для A и B
|
|
A | B
|
or (A,B)
|
битовое «ИЛИ» для A и B
|
|
A ~ B
|
xor (A,B)
|
битовое исключающее «ИЛИ» для A и B
|
|
A << B
|
shl (A,B)
|
сдвиг A на B битов влево
|
|
A >> B
|
shr (A,B)
|
сдвиг A на B битов вправо
|
Внимание: для операции xor используется именно синтаксис "A ~ B" – но не "A ^ B", как в C или Perl!
Бинарные операции сравнения являются предикатами: они возвращают в качестве результата значение 0, если условие ложно, или 1, если оно истинно.
|
A < B
|
lt (A,B)
|
A меньше B?
|
|
A <= B
A ~> B
|
le (A,B)
|
A меньше или равно B?
|
|
A > B
|
gt (A,B)
|
A больше B?
|
|
A >= B
A ~< B
|
ge (A,B)
|
A больше или равно B?
|
|
A == B
|
eq (A,B)
|
A равно B?
|
|
A <> B
A ~= B
|
ne (A,B)
|
A не равно B?
|
(На последнее также важно обратить внимание: запись "A != B" в языке не поддерживается! Однако, вполне допускается "A ~> B" вместо "A <= B"; "A ~< B" вместо "A >= B" и "A ~= B" вместо "A <> B".)
Отдельная операция (компаратор) сравнивает свои операнды на упорядоченность:
|
A <?> B
|
cmp (A,B)
|
Взаимная упорядоченность A и B
|
Она возвращает в качестве результата -1 (если A < B), +1 (если A > B) или 0 (если операнды равны). Она весьма полезна, например, для использования в операциях сортировки, которые будут рассмотрены позднее.
Наконец, для числовых значений также определен ряд стандартных математических функций. Специальной синтаксической записи для них не предусмотрено, только функциональная:
|
floor (X)
|
округление X вниз (до ближайшего целого)
|
|
ceil (X)
|
округление X вверх (до ближайшего целого)
|
|
sqr (X)
|
квадратный корень из X
|
|
exp (X)
|
экспонента от X
|
|
log (X)
|
натуральный логарифм от X
|
|
exp_by (X,Y)
|
возведение X в степень Y
|
|
log_by (X,Y)
|
логарифм Y по основанию X
|
|
pi (X)
|
значение числа «пи», умноженное на X
|
|
sin (X)
|
синус X
|
|
cos (X)
|
косинус X
|
|
tan (X)
|
тангенс X
|
|
asin (X)
|
арксинус X
|
|
acos (X)
|
арккосинус X
|
|
atan (X)
|
арктангенс X
|
|
sinh (X)
|
гиперболический синус X
|
|
cosh (X)
|
гиперболический косинус X
|
|
tanh (X)
|
гиперболический тангенс X
|
Операнд для всех тригонометрических функторов (как и результат для обратных тригонометрических) – задаются, разумеется, в радианах. Для некорректных значений операндов – результатом большинства этих функторов является неопределённость (NaN).
Предусмотрено еще несколько функторов без аргументов (нульарных), возвращающих полезные константы:
|
min_int ()
|
наименьшее целое число
|
|
max_int ()
|
наибольшее целое число
|
|
nan ()
|
NaN («не-число», или арифметическая неопределенность)
|
|
inf_pos ()
|
положительная бесконечность
|
|
inf_neg ()
|
отрицательная бесконечность
|
В языке также доступен генератор равномерно распределенных (псевдо)случайных чисел:
|
rand (N)
|
Возвращает случайное неотрицательное число, меньшее N
|
|
randomize (Seed)
|
Инициализирует генератор СЧ начальным значением Seed.
|
В обеих операциях операнд может быть опущен. Если он не задан в rand() – возвращается произвольное неотрицательное целое. Если он не задан в randomize() – значение Seed также выбирается относительно случайным образом (обычно, на основе текущего времени). Генерируемая последовательность чисел весьма условно "случайна", и вряд ли подходит для "серьёзных" применений (например, криптографических).
Хотя мы говорили о "числовом" типе, на самом деле их два: целый и плавающий. Внутренне они всегда различаются! В большинстве случаев, это не особо принципиально, так как в языке действуют неявные приведения (коерсии) между числовыми типами. Операции, требующие исключительно целые операнды (такие, как битовые и сдвиги) – автоматически приводят плавающие операнды к целому типу; требующие только плавающие операнды (например, все математические) – обобщают целые операнды до плавающих. Некоторые бинарные операции (add, sub, mul, min, max) – выполняются как целые (и возвращают целый результат) только когда оба операнда целые. В противном случае операнды рассматриваются как плавающие, и результат будет такой же. Наконец, в языке предусмотрены и явные приведения:
Приведение целых значений к плавающим вполне тривиально, при обратном – не только теряется дробная часть, но и принудительно ограничивается диапазон, от min_int() до max_int().
Наконец, для проверки принадлежности значения к числовым типам, предусмотрены и логические функторы-предикаты (как и многие другие предикаты в языке, они начинаются с префикса is_):