Skip to the content.

Числовые типы данных

Так NewLang является языком с динамической типизацией, то явное указание типа не влияет на размер памяти, занимаемой переменной и в основном определяет логические ограничения на возможность присвоения переменной значения другого типа.

Информация о типах используется при проверке их совместимости, когда существующему объекту присваивается значение другого типа. Такая операция возможна только когда типы совместимы между собой и допускают автоматическое приведение. Это справедливо как во время парсинга/компиляции исходного теста, так и во время выполнения в режимах интерпретатора и/или скомпилированного файла.

Арифметические типы

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

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

Проблемы без знаковых чисел (из интернета):

Во-первых, вычитание двух без знаковых чисел, например 3 и 5. 3 минус 5 равно 4294967294, т.к. -2 не может быть представлено как без знаковое число. Во-вторых, непредвиденное поведение может возникнуть при смешивании целочисленных значений со знаком и без знака. С++ может свободно преобразовывать числа со знаком и без знака, но не проверяет диапазон, чтобы убедиться, что вы не переполняете свой тип данных.

Имена встроенных арифметических типов: :Int8, :Int16, :Int32, :Int64, :Float16, :Float32, :Float64, :Complex16, :Complex32, :Complex64 говорят сами за себя. Отдельным типом идет логический тип :Bool, который может принимать значения только 0 или 1 (false/true соответственно), и в зависимости от выполняемой операции тоже может быть отнесен к целочисленным типам, так и не входить в их состав (данный подход интерпретации логического типа данных был взят из библиотеки Torch).

// Treat bool as a distinct "category," to be consistent with type promotion
// rules (e.g. `bool_tensor + 5 -> int64_tensor`). If `5` was in the same
// category as `bool_tensor`, we would not promote. Differing categories
// implies `bool_tensor += 5` is disallowed.
//
// NB: numpy distinguishes "unsigned" as a category to get the desired
// `bool_tensor + 5 -> int64_tensor` behavior. We don't, because:
// * We don't want the performance hit of checking the runtime sign of Scalars.
// * `uint8_tensor + 5 -> int64_tensor` would be undesirable.

Доступ к элементам тензора происходит по целочисленному индексу, который начинается с 0. Для многомерного тензора, индексы элемента перечисляются в квадратных скобках через запятую. Поддерживается доступ к элементам через отрицательный индекс, который обрабатывается точно так же, как в Python (-1 последний элемент, -2 предпоследний и т.д.).

Литерал тензор в тексте программы записывается в квадратных скобках с обязательной завершающей запятой, т.е. [1, 2,] — это литерал одномерный тензор из двух чисел. После закрывающей скобки тип тензора может быть указан в явном виде. Если тип не указан, то он выводится автоматически на основании указанных данных и выбирается минимально возможный байтовый размер, который позволяет сохранить все значения без потери точности.

Примеры:

$var_char := 123; # Тип Int8 выводится автоматически
$var_short := 1000; # Тип Int16 выводится автоматически
$var_bool := [0, 1, 0, 1,]; # Тензор из 4 элементов. Тип Bool выводится автоматически
$tensor[10,10]:Int32 := 1; # Тензор Int32 размером 2x2 инициализированный 1
$scalar := $tensor[5,5]; # Присвоить скаляру значение указанного элемента тензора

Рациональные числа

Для специальных расчетов с неограниченной точностью в NewLang используется отдельный тип чисел - рациональные. Они записываются в форме обыкновенной дроби, в которой числитель должен быть целым числом, а знаменатель натуральным (целым без нуля). В качестве разделителя дроби используется обратная косая черта, т.е. 1\1 - рациональное число 1, -5\1 - рациональное числа -5 и т.д.