Основи Delphi 4

Основи Delphi: 4. Операції над цілими числами

Цілочисленні типи даних відіграють ключову роль у створенні будь-якої програми, яка виконуватиметься мікропроцесором. Основні регістри процесора - цілі, а більшість команд працюють саме з цими регістрами. Тому дуже важливо ефективно використовувати операції над цілими числами. Більшість компіляторів вже мають засоби, що дозволяють генерувати оптимальний код, проте програміст повинен раціонально використовувати операції над цілими числами та не створювати зайвих дій у програмі.

32-бітний мікропроцесор оптимально працює з 32-бітними значеннями, тому в мові Delphi рекомендується використовувати типиintegerтаcardinalдля операцій з цілими числами. Однак, інші цілі численні типи також можуть бути використані, якщо необхідно особливим чином визначити певну область пам'яті.

Далі представлені всі цілочисленні типи мови Delphi. У таблиці вказано, скільки пам'яті займає значення того чи іншого типу:

ТипОписРозмір пам'ятіЗначення
byteБеззнакове ціле1 байт0..255
shortintЗнакове ціле1 байт-128..127
wordБеззнакове ціле2 байти0..65535
smallintЗнакове ціле2 байти-32768..32767
cardinallongwordБеззнакове ціле4 байти0..4294967295 або 0..2 32 -1
integerlongintЗнакове ціле4 байти-2147483648..2147483647 або -2 31 ..2 31 -1
int64Знакове ціле8 байт-9223372036854775808..9223372036854775807 або -2 63 ..2 63 -1
uint64Беззнакове ціле8 байт0..18446744073709551615 або 0..2 64 -1
Для того, щоб визначити в програмі, скільки пам'яті займає той чи інший тип, можна використовувати функціюSizeOf:

beginWriteLn( 'byte:', SizeOf(byte)); WriteLn ( 'word: ', SizeOf (word)); WriteLn(' cardinal: ', SizeOf(cardinal)); WriteLn( 'uint64: ', SizeOf(uint64));

Структура цілісного значення

Для типуbyteзі структурою зрозуміло: займає один байт, від 0 до 255, тобто. від 00000000 до 11111111 у двійковому вигляді. У структурі числа немає інформації про знак числа, тому тип і називається беззнаковий.

Для знакового типуshortintнеобхідно зберігати інформацію про знак - для цього достатньо одного старшого (першого зліва) біта. Якщо він дорівнює 0, то число - позитивне (або нульове) і його значення варіюються від 0 до 127, тобто. від 00000000 до 01111111. Якщо старший біт дорівнює 1, то число - негативно, і 7 біт, що залишилися, є різницею між числом 128 і модулем шуканого числа (так званийдодатковий кодчисла). Наприклад:

-111111111
-211111110
-311111101
-12810000000
Інші цілі типи вимагають більше, ніж 1 байт пам'яті. Для зручності байти значення у пам'яті записують у зворотному порядку. Наприклад число 123456 типуinteger, яке в двійковому та шістнадцятковому вигляді записується як

у пам'яті буде представлено у вигляді

01000000 11100010 00000001 00000000

Щоб переконатися в тому, що байти значення в пам'яті записуються у зворотномуУ порядку можна провести експеримент. Візьмемо у числа 789 (або 0000001100010101) типуwordтільки перший байт, і він повинен дорівнювати 21 (або 00010101), а не 3 (або 00000011) за прямого порядку:

beginA := 789; P := @A; // покажчик на область пам'яті змінної A

WriteLn(A); WriteLn(PByte(P)^); // виводимо перший байт області пам'яті // який вказує P ReadLn;end.

Операції над цілими числами можна розділити наарифметичнітапобітові. Арифметичні операції представлені в таблиці:

ЗнакОпераціяприкладРезультат
+Додавання7 + 411
-Віднімання7 - 43
*множення7*428
/Поділ7 / 41.75 (завжди речове)
divПоділ без залишку7 div 41 (завжди ціле)
modЗалишок від ділення7 mod 43
Побітові (bitwise) операції відрізняються від арифметичних тим, що взаємодіють не самі числа, а відповідні біти. Для кожної пари бітів виконується будь-яка логічна операція, і результат побітової операції складатиметься з результатів логічних операцій кожної пари біт.

ЗнакОпераціяприкладРезультат
notЗапереченняnot 5 (¬ 00000101)-6 (11111010)
andПобітове логічне "І"5 і 7 (00000101 ^ 00000111)5 (00000101)
orПобітове логічне "АБО"5 або 7 (00000101 v00000111)7 (00000111)
xorПобітове логічне "що виключає АБО"5 xor 7 (00000101 xor 00000111)2 (00000010)
shlЗсув бітів вліво22 shl 2 (00010110)88 (01011000)
shrЗсув бітів праворуч22 shr 2 (00010110)5 (00000101)

Значення одного цілого типу наводяться до іншого цілого типу без будь-яких проблем. Слід врахувати, якщо новий тип займає у пам'яті менше байт, ніж старий тип, то зайві байти просто відсікаються. Це також зручно, якщо необхідно отримати перші кілька байт цілого чисельного значення (наприклад, перший байт значення типу word або перші два байта значення типу cardinal). Однак, якщо тип знаковий, а саме значення негативне, то приведення до типу, що займає менше пам'яті, може призвести до позитивного результату. Наприклад, наводячи значення -1000 (11111100 00011000) типуsmallintдо типуshortint, в результаті отримаємо 24 (00011000).

Значення результату будь-якої цілої операції завжди має тип, який займає в пам'яті максимум з типів операндів. Наприклад, integer + word = integer, int64 – byte = int64. Це може створити проблеми під час операції множення, коли результат необхідно отримати з типомint64. У конструкції

вираз (a * b) має типinteger, а неint64, і значення може переповнитися. У цьому випадку слід привести один із операндів до типуint64. Явне приведення до якогось типу описується так:

У такому разі текст програми виглядає так: