Глава 3 · Выражения и операции
Системы счисления и запись целых чисел
Когда важны отдельные разряды числа, десятичная запись читается плохо. Для таких мест служат шестнадцатеричный литерал с префиксом &H и двоичный с префиксом &B; они задают то же числовое значение, и система счисления не становится частью типа.
Одно число в трёх записях
Записи 10, &HA и &B1010 обозначают одно число, которое после разбора участвует в обычных операциях INTEGER или LONG. Отдельных двоичных и шестнадцатеричных типов нет.
Шестнадцатеричная цифра задаёт четыре двоичных разряда, поэтому F соответствует 1111, а &H2A и &B101010 имеют одно десятичное значение 42. Такая запись удобна для разрядов и масок.
Шестнадцатеричная запись
&H<шестнадцатеричные цифры>
После &H требуется хотя бы одна цифра от 0 до 9 или буква от A до F. Регистр префикса и букв не различается, поэтому &HFF и &hff задают 255. Ведущие нули разрешены: &H000F равно 15; разрядность типа они не задают.
Двоичная запись
&B<двоичные цифры>
После &B записывается одна или несколько цифр 0 и 1. Префикс не различает регистр, ведущие нули допускаются, поэтому &B1010, &b1010 и &B00001010 равны 10.
Цифры от 2 до 9, буквы и подчёркивания внутри двоичной записи недопустимы: &B102 отклоняется целиком как неверный литерал, а не читается как допустимое начало с отдельной цифрой в конце.
Тип и предел величины
Префиксный литерал задаёт неотрицательную величину, и её значение определяет обычный тип литерала:
| Величина | Тип | Пример |
|---|---|---|
| От 0 до 2147483647 | INTEGER | &H7FFFFFFF; до 31 значащей двоичной единицы |
| От 2147483648 до 9223372036854775807 | LONG | &H80000000, &H7FFFFFFFFFFFFFFF; до 63 значащих двоичных разрядов |
| Больше 9223372036854775807 | Недопустимо, MB0004 | &H8000000000000000; единица с 63 двоичными нулями |
&HFFFFFFFF означает положительное LONG 4294967295, а не -1, и двоичный литерал из 32 единиц даёт то же значение. Напротив, &H0000000000000001 остаётся INTEGER независимо от количества ведущих нулей.
Ожидаемый числовой тип может изменить тип литерала с проверкой диапазона: DIM wide AS LONG = &HFF создаёт LONG, а DIM exact AS DECIMAL = &B1010 создаёт DECIMAL. Число при этом не становится строкой или BOOLEAN.
Префиксные литералы не поддерживают дробную часть, показатель степени, разделители разрядов и суффиксы типа. Записи с префиксами 0x, 0b и &O числовыми литералами Axiom не являются.
Минус перед литералом
-&H<шестнадцатеричные цифры>-&B<двоичные цифры>
Минус является отдельной операцией: сначала проверяется положительная величина литерала, затем меняется её знак. Выражения -&HFF и -&B1010 дают -255 и -10.
У отдельно стоящего -&H80000000 тип LONG, поскольку положительная часть уже превышает INTEGER. Но в объявлении DIM n AS INTEGER = -&H80000000 конечное значение -2147483648 помещается в INTEGER и принимается.
Величина 9223372036854775808 превышает LONG ещё до применения минуса, поэтому -&H8000000000000000 отклоняется с MB0004. Минимальный LONG получают целочисленным выражением CLNG(1) << 63. Префикс не обозначает интерпретацию старшего разряда как знака.
Вычисления с префиксными числами
Для этих чисел действуют обычные арифметические операции и сравнения:
PRINT &H10 + &B11
PRINT &H10 \ &B11
PRINT &H10 MOD &B11
PRINT &HA = &B1010
Результат:
19
5
1
TRUE
Сложение &H7FFFFFFF + 1 переполняет INTEGER и вызывает MB3008; чтобы вычислить в LONG, тип задаётся до сложения: CLNG(&H7FFFFFFF) + 1. Переполнение уже выбранного типа не приводит к его автоматическому расширению.
Обычное деление этих целых чисел возвращает DOUBLE, степень также возвращает DOUBLE. Префикс не меняет правила операций и числового продвижения.
Вывод числа в другой системе
PRINT без форматирования выводит число десятичным текстом, поскольку исходный префикс в значении не хранится. В интерполяции формат X получает шестнадцатеричный текст, B — двоичный; оба применимы к INTEGER и LONG:
DIM value AS INTEGER = &H2A
PRINT value
PRINT $"{value:X}"
PRINT $"{value:B}"
PRINT $"{value:X4}"
PRINT $"{value:B8}"
Результат:
42
2A
101010
002A
00101010
Число после буквы формата задаёт минимальное количество цифр: короткий текст дополняется нулями слева, длинный не обрезается. Префиксы &H и &B не добавляются, но их можно включить в обычный текст: $"&B{value:B8}". Буква формата приводится к верхнему регистру, поэтому x4 тоже даёт заглавные шестнадцатеричные цифры.
Отрицательный INTEGER или LONG форматируется в дополнительном коде на 32 или 64 разрядах без минуса: INTEGER -1 даёт FFFFFFFF или 32 единицы, LONG -1 даёт FFFFFFFFFFFFFFFF или 64 единицы. Дополнительный код здесь обозначает битовую запись отрицательного целого; подробнее в статье побитовых операций.
Минимальная ширина больше обычной дополняет текст нулями и не меняет INTEGER на LONG; для изменения разрядности до форматирования служит CLNG.
X и B для DOUBLE или DECIMAL, как и неверный числовой формат, вызывают перехватываемую MB3007. У нечислового значения формат игнорируется: BOOLEAN выводится как TRUE или FALSE. Полный договор находится в статье интерполяции строк.
Строка с цифрами и литерал
Строка с цифрами не является числовым литералом. Для INTEGER и LONG оператор INPUT принимает только десятичную запись, поэтому ответы &HFF и &B1010 приводят к MB3003.
VAL возвращает DOUBLE: VAL("1010") даёт десятичное значение 1010, а вызовы VAL("&HFF") и VAL("&B1010") возвращают 0, поскольку префиксный разбор строк этой функцией не поддерживается. Правила частичного разбора текста описаны в статье преобразования чисел и текста. Встроенных HEX и BIN нет; для вывода используется интерполяция.
Диагностика
MB0003: префикс без цифр, недопустимая цифра или примыкающий буквенный, цифровой либо подчёркнутый суффикс.MB0004: величина литерала превышает максимум LONG.MB2018: литерал не помещается в ожидаемый тип, например приDIM n AS INTEGER = &H80000000.MB3008: переполнение арифметической операции.MB3007: неподдерживаемый числовым типом X/B или неверный числовой формат.MB3003: префиксный текст передан числовой цели INPUT.
Запускаемые примеры
См. также
Для разрядов и масок служат побитовые операции и сдвиги, точные пределы собраны в диапазонах типов. Логические значения описаны в статье BOOLEAN.