Правила языка: числовые типы и числовые константы
Встроенные числовые типы делятся на целые числа со знаком, целые числа без знака и числа с плавающей точкой.
Замечание: символы, из которых состоят имена встроенных числовых типов, могут быть разделены
пустым оператором.
Тип: целое со знаком
= +- ( 1 | 2 | 3 ... 62 | 63 )
Имя типа начинается с последовательности символов «+-», которая говорит о том,
что числа этого типа имеют как положительные, так и отрицательные значения, а так же ноль.
Следующее за «+-» число от 1 до 63 означает, что число имеет соответстующую разрядность.
Типы «+-1», «+-2» ... «+-63» аналогичны типам «i1», «i2» ... «i64» в LLVM.
В языке PL/1 при объявлении целых чисел так же может указываться их разрядность:
DCL (I, J, K) BIN FIXED (2;
Один разряд отводится под знак числа.
Так же, как и в LLVM, реальная разрядность числа будет такой, какую назначит компилятор исходя из задания на компиляцию.
Такое обозначение типов универсально, оно «интернационально» и независимо от естественного языка, который использует разработчик.
Однако в англоязычном варианте имена типов «+-31» или «+32» могут заменяться именами «i31» и «ui32».
В русском варианте — «ц31» и «бц32» соответственно.
Поскольку последовательность символов «+-» уникальна (такая последовательность больше нигде не применяется в языке),
то конструкция +-ЧИСЛО имеет однозначно трактуемый синтаксис.
Примеры:
+-7 // Тип «целое со знаком»; требует 8 битов в памяти
+-31 // Тип «целое со знаком»; требует 32 бита в памяти
+-45 // Тип «целое со знаком»; требует 46 битов в памяти
+16 // Тип «целое без знака»; требует 16 битов в памяти
+24 // Тип «целое без знака»; требует 24 бита в памяти
Замечание: в первой версии языка было принято решение ограничиться 32 разрядами.
Для написания компилятора языка на самом языке (раскрутка компилятора второй версии)
этой разрядности достаточно.
Тип: целое без знака
= + ( 1 | 2 | 3 ... 63 | 64 )
Имя типа начинается со знака «+», который говорит о том,
что числа этого типа имеют исключительно положительные значения, а так же ноль.
Следующее за ним число означает разрядность от 1 до 64.
Типы «+1», «+2» ... «+63» аналогичны типам для целых со знаком «+-1», «+-2» ... «+-63», только у них нет знакового разряда.
В LLVM прямого аналога этого типа нет.
В реальности числа этого типа имеют разрядность такую же, как и процессор.
Поскольку унарный знак «+» отсутствует в языке по причине его бессмысленности
(в Си унарный «+» существует для «симметрии» с унарным «-», что можно считать пижонством),
то конструкция +ЧИСЛО имеет однозначно трактуемый синтаксис.
Замечание: лексический анализатор отличает бинарный «+» в выражении
а + 32 // операнд + константа
от типа
+ 32 // + константа — левого операнда нет
по отсутствию операнда слева.
Примеры:
+1 // Тип «целое без знака»; требует 1 бит в памяти. Булев тип.
+16 // Тип «целое без знака»; требует 16 битов в памяти
+49 // Тип «целое без знака»; требует 49 битов в памяти
О разрядности целых типов и проверках переполнения
Как известно, при операциях сложения, вычитания и умножения целых чисел в некоторых случаях может возникнуть переполнение.
Например, если переменные a , b , c и d — 32-разрядные, а e и f — 31-разрядные,
то при сложении:
a = b + c // переполнение возможно
d = e + f // переполнение невозможно
То есть результат суммирования должен храниться в ячейке с разрядностью на 1 больше, чем наибольшая разрядность операндов.
При умножении разрядность, в которую помещается результат, является суммой разрядности операндов.
Например, если x — 8-разрядное, y — 9-разрядное, V — 16-разрядное, а W — 17-разрядное, то
V = x * y // переполнение возможно
W = x * y // переполнение невозможно
В первых случаях обоих примеров результат сложения может не поместиться в ячейку, хранящей результат.
Тогда программист обязан предусмотреть в программе обработку этого особого случая, а компилятор сгенерировать соответствующий код.
Во вторых случаях обоих примеров результат сложения может гарантированно поместиться в ячейку, хрянящей результат.
Тогда в программе обработка особого случая не нужна, компилятор не генерирует проверяющий код.
Достаточный целый тип
Достаточный целый тип — это минимальный из возможных целых типов, разрядности которого достаточно, чтобы хранить нужное значение.
Достаточный целый тип со знаком
= Тип: целое со знаком
Разрядность типа зависит от величины константы,
знак типа зависит от знака константы.
Достаточный целый тип без знака
= Тип: целое без знака
Разрядность типа зависит от величины константы,
знак типа зависит от знака константы.
Примеры:
-
для чисел 0 и 1 достаточным будет тип
+1 ,
-
для чисел 2 и 3 достаточным будет тип
+2 ,
-
для чисел от 4 до 7 достаточным будет тип
+3 ,
-
для чисел от 512 до 1023 достаточным будет тип
+10 ,
-
для числа -1 достаточным будет тип
+-1 ,
-
для чисел -2 и -3 достаточным будет тип
+-2 ,
-
для чисел от -4 до -7 достаточным будет тип
+-3 ,
-
для чисел от -4096 до -8191 достаточным будет тип
+-13 ,
Двоичное представление констант целого типа
Константа в двоичном виде
= 2 \ { Двоичная цифра }1
Примеры:
2 \ 1 // целое число 1, достаточный тип: +1
2 \ 0 0 0 0 0 111 1111 // целое число 127, достаточный тип: +7
2\ 1 (* комментарий *) 0 // целое число 2, достаточный тип: +2
2 (* ещё комментарий *) ...
\ 1 0 0 0 ...
0 0 0 1 // целое число 129, достаточный тип: +8
Десятичное представление констант целого типа
Константа в десятичном виде
= [ - ] { Десятичная цифра }1
Знак минуса перед десятичными цифрами – унарный
Примеры:
21 // целое число 21, достаточный тип: +5
- 6 0 0 0 0 // целое число -60000, достаточный тип: +-17
998 (* миллионы *) ...
997 (* тысячи *) ...
996 // целое число 998997996, достаточный тип: +30
Шестнадцатиричное представление констант целого типа
Константа в шестнадцатиричном виде
= 1 6 \ { Шестнадцатиричная цифра }1
Примеры:
16\d // целое число 13, достаточный тип: +4
16 \ FFFF FFFF FFFF FFFF // целое число 4 394 967 295, достаточный тип: +32
16 \ 7FFF FFFF FFFF FFFF // целое число 2 147 483 647, достаточный тип: +31
16 \ 1FFF FFFF FFFF FFFF // целое число 536 870 911, достаточный тип: +29
1 (* комментарий *) 6\ 03 // целое число 3, достаточный тип: +2
Константы целого типа
Константа целого типа
[ ( Тип: целое со знаком | Тип: целое без знака ) : ]
( Константа в двоичном виде
| Константа в десятичном виде
| Константа в шестнадцатиричном виде )
Примеры:
+17:16\f // целое число 15, тип: +17
+-7: -1 // целое число -1, тип: +7
+32: 16 \ 0FFF FFFF // целое число 268 435 455, тип: +32
+-31: 16\ 7FFF FFFF FFFF FFFF // целое число 2 147 483 647, тип: +-31
+-31: 16\ FFFF FFFF FFFF FFFF // все левые биты установлены в 1,
// включая знак; целое число равно -1, тип: +-31
+ - 3 1 : 3 3 // целое число 33, тип: +-31
Плавающие типы и числа с плавающей точкой
Имя типа начинается с символа волнистой линии «~», которая намекает на волны и плавание,
а в условиях цифрового мира — на числа с плавающей точкой.
Можно вспомнить о символе двойной волнистой линии «≈»: он означает не тождественное равенство, а приблизительное.
А числа с плавающей точкой, как мы знаем, обеспечивают вычисления с определённой погрешностью.
По ряду причин у чисел с плавающей точкой видимых проблем, подобных проблемам с переполнением чисел целого типа, меньше.
Пока что решено остановиться на трёх разновидностях, аппаратно поддерживаемых наиболее популярными платформами.
Замечание: в первой версии языка было принято решение отказаться от реализации плавающей арифметики.
Для написания компилятора языка на самом языке (раскрутка компилятора второй версии) плавающая арифметика совершенно не нужна.
С появлением реализации плавающей арифметики в следующих версиях этот раздел будет дополнен.
Тип: плавающее
= ~ ( 32 | 64 | 80 )
Константы плавающего типа
Константа плавающего типа
( [ ( Тип: плавающее ) : ] [ - ] Константа в десятичном виде
[ . Константа в десятичном виде ] )
|
( [ - ] Константа в десятичном виде .
Константа в десятичном виде )
Примеры:
~32: 1 // 32-разрядное число с плавающей точкой,
// равное 1.0
~64: -3 // 64-разрядное число с плавающей точкой,
// равное -3.0
~80: 2.718281828459045 // 80-разрядное число с плавающей точкой,
// равное числу Эйлера
3.1415926535 // число π с плавающей точкой,
// по умолчанию разрядность - 64
Опубликовано: 2023.05.02, последняя правка: 2024.07.15 22:23
Отзывы
✅ 2023/05/22 10:36, kt #0
Пример на PL/1, скорее, вот так будет: DCL (I,J,K) BIN FIXED(24); при этом именно 24 непродуктивно, теряется байт из-за одного бита. На PL/1, скорее, был бы FIXED(23), т.е. кратно 8 разрядам. Хотя формально допустимо и 24, но создатели компиляторов кроме, может быть, проверки присвоения констант кривыми битами в байтах обычно не заморачиваются.✅ 2023/05/23 00:43, Автор сайта #1
Поправил. Давно не брал в руки шашек не имел дело с PL/1, запамятовал. Добавить свой отзыв
Написать автору можно на электронную почту mail(аt)compiler.su
|