Разделы сайта находятся в разработке.

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

Числа и тензоры

Числовые типы — простые (скалярные) типы данных TrustLang. Основы типизации описаны на странице Система типов, а массивы, диапазоны и (в перспективе) тензоры — в разделе Диапазоны, массивы и тензоры.

Целые числа

Имена целых типов соответствуют их разрядности: :Int8, :Int16, :Int32, :Int64. Целочисленный литерал получает минимальный знаковый тип, в который влезает его значение (например, 5 → :Int8), а значение, не помещающееся в :Int64, становится :BigInteger. Тип литерала можно задать явной аннотацией литерал :Type (например, 1 :Bool, 255 :Int16) — при выходе за диапазон типа возникает ошибка компиляции, а не молчаливое переполнение.

Для взаимодействия с нативным C++-кодом у целых есть беззнаковые синонимы (:Byte, :Word, :DWord, :UInt16/:UInt32/:UInt64, …), которые применяются при вызове нативных функций. В арифметике предпочтительны знаковые типы — так удаётся избежать классических проблем беззнаковой арифметики (например, вычитания, дающего огромное «отрицательное» значение).

Контроль целочисленного переполнения

Арифметика знаковых машинных целых (+, -, * и составные +=, -=, *=) контролируется на переполнение: результат операции проверяется встроенной функцией __builtin_*_overflow, и при переполнении выбрасывается программное исключение trust::IntMinus (ловится trust-блоком {- ... -} и конструкцией try), а не возникает неопределённое поведение (UB), как в C++. Сообщение исключения содержит локацию исходного кода в формате файл:строка: (как у @assert), например rational.src:8: integer overflow in '*='.

Опция -foverflow-check / -fno-overflow-check (по умолчанию включена) управляет контролем. Проверяются только знаковые машинные целые (:Int8…:Int64); беззнаковые типы по определению заворачиваются (wrap), :BigInteger/:Rational имеют произвольную точность, а /, //, % и битовые операции не переполняются и не проверяются.

Дополнительно контролируется унарный минус (-x: переполнение при -INT_MIN) и целочисленное деление /////= — предохранители от деления на ноль и от INT64_MIN / -1 (undefined behavior в C++). Все нарушения также приводят к перехватываемому trust::IntMinus.

Логический тип

Логический тип :Bool принимает только значения 0 или 1 (false/true). Он выделен в отдельную категорию (значения @true/@false в DSL — это 1 :Bool/0 :Bool) и в зависимости от операции может вести себя как целочисленный. Явная 0 :Bool/1 :Bool-аннотация создаёт именно логическое значение.

Числа с плавающей точкой

Типы с плавающей точкой соответствуют разрядности: :Float16, :Float32, :Float64 (синонимы :Single, :Double). Разряды числа можно разделять знаком подчёркивания для читаемости: 10_000.

Рациональные числа и произвольная точность

Для вычислений с неограниченной точностью используются рациональные числа: это дробь \( \frac{m}{n} \), где числитель m — целое, а знаменатель n — натуральное (больше нуля). В качестве разделителя дроби используется обратная косая черта: 1\1 — единица, -55\3 — дробь \( \frac{-55}{3} \). Арифметика рациональных чисел строится на :BigInteger (GMP) и не теряет точность; смешивание с числами с плавающей точкой требует явного преобразования.

Показ длинных чисел

Полное значение числа произвольной точности может быть очень длинным. Для показа (в логах, отчётах, диагностике) у :BigInteger есть метод display(L), возвращающий строку вида голова...хвост (N), где L — число цифр в начале и конце, а N — общее число десятичных цифр:

x :BigInteger := 123456789012345678901234567890;
@print('{}', x.display(3));   # 123...890 (30)

Если цифр немного (N <= 2L + 1), возвращается полное число. Знак выводится впереди, а N считает цифры без учёта знака.

Метод display(L) предназначен только для показа: его результат — строка, из которой нельзя восстановить точное значение числа (это не round-trip представление). Точное десятичное представление даёт обычный вывод значения ({} в форматной строке).

Аналогичный метод есть и у рациональных чисел :Rational: display(L) сокращает каждый компонент дроби независимо (числитель и знаменатель — :BigInteger), например 123...890 (30)\45...678 (5).

См. также