Ни для кого не секрет, что в языке ABAP есть встроенный тип данных p (англ. packed number — упакованное число).

В то же время, в ABAP-словаре есть типы данных DEC, QUAN и CURR — упакованные числа в формате BCD, соответствующие типу данных p.

Наверняка, вы уже использовали эти типы данных для хранения сумм или количества чего-либо, но возможно вы не задумывались как они устроены.

Давайте с этим разберемся.

Двоично-десятичный код

BCD (англ. binary-coded decimal — двоично-десятичный код) — такой код, при котором каждый десятичный разряд числа записывается в виде его четырёхбитного двоичного кода.

Почему в виде четырехбитного кода? Потому что именно 4-х бит достаточно для того, чтобы представить диапазон числе от 0 до 9.

Целые числа

Рассмотрим пример.

Целое число 42710 можно записать как 0100 0010 0111BCD.

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

Исходя из этого в ABAP редакторе при объявлении переменной типа p нам потребуется указать длину не менее 2 байт.

DATA lv_p TYPE p LENGTH 2.

Для того, чтобы определить, сколько десятичных разрядов может хранить переменная типа p используйте следующую формулу:

2*n — 1.

где n — это количество байт (для типа p это LENGTH).

Таким образом, переменная lv_p из нашего примера может хранить число с 3-мя десятичными разрядами, например 427.

При этом в ABAP-словаре, например, при создании домена, нам необходимо указывать не количество байт как в ABAP редакторе, а количество десятичных разрядов числа (количество цифр в числе). Обратите внимание, что после указания числа позиций автоматически заполнится поле «Длина вывода».

Числа с десятичной частью

Теперь давайте рассмотрим похожий пример, но возьмем число побольше и с десятичными разрядами. Например 1287.58.

Для хранения 6-ти цифр этого числа (4 в целой части и 2 в десятичной) нам требуется 4 байта. Поэтому, при объявлении переменной в ABAP редакторе указываем длину минимум 4.

DATA lv_p TYPE p LENGTH 4 VALUE '1287.58'.

Проверяем себя. Используем формулу 2*n — 1.

2 * 4 — 1 = 7.

Т.е. в переменной типа p c длиной 4 байта мы можем хранить максимум 7 цифр. Отлично!

Если указать LENGTH 3, то этого будет недостаточно, т.к. в 3-х байтах мы можем хранить только 5 чисел, а у нас их 6.

2 * 3 — 1 = 5.

При попытке сохранить в такую переменную наше число будет поднято исключение cx_sy_conversion_overflow.

Идем дальше. В ABAP словаре при создании домена нам необходимо будет указать «Число позиций» минимум 6, т.к. в нашем числе 6 цифр. Из этих 6-ти позиций 2 будут выделены для хранения десятичных разрядов.

Длина вывода автоматически заполнится значением 7, т.к. одна позиция будет хранить разделитель тысяч ‘,’ (запятая, т.е. 1,287.58 ).

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

Вместо заключения

Ограничения типов данных можно посмотреть здесь.

Надеюсь, эта заметка вам пригодится, а чтобы не потерять ее подписывайтесь на telegram канал.

Изображение поста взято здесь: Abstract vector created by rawpixel.com — www.freepik.com


P.S. Ира, Саша — спасибо за тему)

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.