МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
/
Кафедра ЕОМ
Лабораторна робота № 2
"Перетворення типів даних"
Вибір варіанта 26%4=2, 4%4=0 => v0, v4, w2, w7.
const int x_1= 026040;
const double y_2= 4. 26 e +2;
char v0
char v4
long w2
short w7
Львів – 2011
1. Мета роботи
Дослідження методів та засобів явного та неявного перетворення типів даних.
2. Постановка задачі
Завдання 1:
Визначити, які неявні перетворення типів будуть відбуватись при обчисленнях. З’ясувати, чи відбудуться втрати значимості даних. Хід міркувань підтвердити програмними результатами. В звіти пояснити кожне перетворення і метод, яким воно здійснено.
typedef unsigned int type_0;
typedef unsigned short int type_1;
typedef unsigned long int type_2;
typedef signed short int type_3;
typedef signed int type_4;
typedef signed long int type_5;
typedef bool type_6;
typedef char type_7;
typedef wchar_t type_8;
typedef float type_9;
typedef double type_10;
typedef long double type_11;
type_8 x0=0;
type_0 x1=26;
type_4 x2=2;
type_4 x3=3;
type_5 x4=4;
type_2 x5=5;
type_1 x6=6;
type_8 x7=7;
type_0 x8=8;
type_4 x9=9;
type_4 x10=10;
type_2 x11=11;
/* 1 */ x1 = x1 – 0xFFFFFFFA;
/* 2 */ x3 = ’a’ + x0 – x2;
/* 3 */ x7 = x4 + x5 + x6 * 0.1;
/* 4 */ x8 = x9 + x10 – x11*10;
Завдання 2
Визначити, які явні і неявні перетворення типів будуть відбуватись. Результати обчислень підтвердити програмними результатами. В звіти пояснити кожне перетворення і кожний отриманий результат.
Вибір варіанта 26%4=2, 4%4=0 => v0, v4, w2, w7.
const int x_1= 026040;
const double y_2= 4. 26 e +2;
int x = х_1;
double y = y_2;
char v0=*reinterpret_cast<char*> (&x) +3; printf("%d %x %c \n", v0,v0,v0);
char v4 = static_cast< char > (x)+22; printf("%d %x %c \n", v4,v4,v4);
long w2=static_cast<long>(y)+55; printf("%lx %lu %ld \n", w2,w2,w2);
short w7=*(reinterpret_cast<short*>(&y)+2)+2; printf("%x %u %d \n", w7,w7,w7);
Алгоритм розв’язання задачі
Обчислення значень виразів в операторах мови C++ забезпечується виконанням операцій і викликом функцій. Операції використовують операнды, функції вимагають параметрів. Операнды і параметри характеризуються типами. У мові C++ не існує операцій, що, наприклад, забезпечували б додавання або множення операндів різних типів. Якщо в виразах зустрічаються операнды різних типів, то вони перетворюються до загального типу відповідно до деякого набору правил. Загалом, автоматично здійснюються тільки такі перетворення, що мають зміст, такі, наприклад, як перетворення цілого в дійсне. Вирази ж, позбавлені змісту, такі, наприклад, як використання змінної типу float в масивах як індекса, заборонені. Нехай, наприклад, потрібно виконати таку операцію:
int ix = 0;
ix = 5.74 + 1; // зазвичай компілюється з попередженням
В цьому прикладі додаються літерали різних типів: 5.74 типу double та 1 типу int. Мова програмування C++ не може безпосередньо додати подібні операнди, спочатку відбувається зведення їх до одного типу. Для цього існують правила перетворення арифметичних типів. Загальний принцип такий: перейти від операнда меншого типу до більшого, щоб не втратити точності обчислень. В наведенному прикладі ціле значення 1 трансформується в тип double, і тільки після цього відбувається додавання. Таке перетворення виконується незалежно від бажання програміста, відтак воно і отримало назву неявного перетворення типу. Результат додавання двох чисел типу double теж має тип double. В прикладі це значення рівне 6.74. Тепер його необхідно присвоїти змінній ix. Тип змінної ix і тип результату обчислень 6.74 не співпадають, отже, тип результату буде приведений до типу змінної, тобто до типу int. Перетворення double в int відбувається автоматично, шляхом відкидання дробової частини (а не заокругленням її). Таким чином, 6.74 перетворюється в 6, і даний результат присвоюється змінній ix. При такому перетворенні може виникати втрата точності, тому більшість компіляторів видають попередження.
Оскільки компілятор не заокруглює числа при перетворенні double в int, то при необхідності програміст повинен робити це сам, наприклад:
double dx = 5.74;
int ix = 1;
ix = dx + ix + 0.5; // перетворення із заокругленням
В цьому прикладі змінна іх набуває значення 7.
За бажанням можна здійснити явне перетворення типів:
ix = static_cast< int >(5.74) + 1;
В цьому прикладі явно вказується компілятору привести величину 5.74 до типу int, а не додержуватись правил за замовчуванням.
Система тестів
Завдання 1
x1 = x1 – 0xFFFFFFFA
int x1 = 1A
ВПК: 1A000000
Перетворення:
Int 0xFFFFFFFA
int −> usigned int
Mетод: перетворюється до без знакового, результат інтерпретується як без знакова величина.
ВПК: FAFFFFFF −> FAFFFFFF
Комп’ютер знає тільки дію додавання, вираз набуде вигляду:
x1 = x1+ (–0xFFFFFFFA)
–0xFFFFFFFA => 0x00000006
x1=26+6=32
Результат: 32
x3 = ’a’ + x0 – x2
int х2 =2
ВПК: 02000000
Перетворення:
Символьна константа 'a' - значення 9710 або 6116 за таблицею ASCII
char −> signed int
Mетод: розширення знаком
ВПК: 61 −> 61 00 00 00
wchar_t х0=0
wchar_t −> signed int
Mетод: розширення знаком
ВПК: 00 00 −> 00 00 00 00
x3=97+0-2=95
Результат: 95
x7 = x4 + x5 + x6 * 0.1
double 0.1
За допомогою 1 лабораторної роботи поглянем double 0.1 :
ВПК: 9A 99 99 99 99 99 B9 3F
Перетворення:
signed long x4=4
signed long −> double
Mетод: представляється як double, можлива втрата точності
ВПК: 04 00 00 00 −> 00 00 00 00 00 00 10 40
unsigned long x5=5
unsigned long −> signed long
Mетод: збереження всіх байтів, старший біт стає знаковим
ВПК: 05 00 00 00 −> 05 00 00 00
signed long −> double
Mетод: представляється як double, можлива втрата точності
ВПК: 05 00 00 00 −> 00 00 00 00 00 00 14 40
unsigned short x6=6
unsigned short −> int
Mетод: розширення 0 до 4 байт
ВПК: 06 00 −> 06 00 00 00
int −> double
Mетод: ціле число представляється як дійсне
ВПК: 06 00 00 00 −> 00 00 00 00 00 00 18 40
x7=4+5+6*0.1=9.6
Результат: 9.6
Перетворення:
double 9.6
double −> long
Mетод: усікання дробової частини
ВПК:33 33 33 33 33 33 23 40 −> 09 00 00 00
long −> wchar_t
Mетод: збереження двох молодших байтів
ВПК: 09 00 00 00 −> 09 00
Результат: 9
x8 = x9 + x10 – x11*10
int x11=11
ВПК: 0B 00 00 00
Перетворення:
signed int х9=9
signed int −> unsigned long
Mетод: розширення знаком, інтерпретується як без знакове число
ВПК:09 00 00 00 −> 09 00 00 00
signed int х10=10
signed int −> unsigned long
Mетод: розширення знаком, інтерпретується як без знакове число
ВПК:0A 00 00 00 −> 0A 00 00 00
int 10
signed int −> unsigned long
Mетод: розширення знаком, інтерпретується як без знакове число
ВПК: 0A 00 00 00 −> 0A 00 00 00
x8=9+10-11*10=19-110= -9110=>-5B16
ВПК 5B : 5B 00 00 00 , оскільки - 5B зробивши інверсію та додавши 1
=> A5 FF FF FF
A5 FF FF FF16 = 429496720510
Результат: 4294967205
Перетворення:
unsigned long −> unsigned int
Mетод: збереження всіх бітів
ВПК: A5 FF FF FF −> A5 FF FF FF
Результат: 4294967205
Завдання 2
const int x= 026040;
x= 0260408=2C2016
const double y= 4.26e+2;
y= 4.26e+2=426.0
char v0=*reinterpret_cast<char*> (&x) +3
Нехай у=*reinterpret_cast<char*> (&x)
ВПК int х: 20 2С 00 00
char займає 1 байт, маєм що у=2016=0010 00002 , оскільки, знак “+”,
отримаєм: 32+3=35
Відповідь: 35 23 #
35 – отриманий результат в 10-ій системі числення;
23 – отриманий результат в 16-ій системі числення (2316=3510);
'#' – З таблиці ASCII під номером 3510 знаходиться символ '#' ;
char v4 = static_cast< char > (x)+22
ВПК х: 20 2С 00 00
Оскільки, char займає 1 байт, берем перший 2016=3210
32+22=54
Відповідь: 54 36 6
1) 54 – отриманий результат в 10-ій системі числення;
36 – отриманий результат в 16-ій системі числення(5410=3616);
'6' – З таблиці ASCII під номером 5410 знаходиться символ '6'
long w2=static_cast<long>(y)+55
Оскільки, double- дійсне чило а long- ціле,
то відкидається дробова частина: 426.0 −> 426 і додається 55
426+55=481
Відповідь: 1Е1 481 481
1Е1 – отриманий результат в 16-ій системі числення(48110=1Е116) ;
481 – отриманий результат представляється як unsigned long, оскільки тип без знаковий а число додатнє , то залишиться таким же;
481 – отриманий результат в 10-ій системі числення
short w7=*(reinterpret_cast<short*>(&y)+2)+2
y=*(reinterpret_cast<short*>(&y)+2)
ВПК х: 00 00 00 00 00 А0 7А 40
&y +1 +2
Оскільки, short займає 2 байта,
то ВПК у : 00 А0А0 0016 = 1010 0000 0000 0000 00002
0101 1111 1111 1111 1111
1
0110 0000 0000 0000 0000
– приймається як знакове, в результаті
отримаєм 0110 0000 0000 0000 0000 відповідно воно дорівнює -60 0016 = -2457610
-24576 + 2 = -24574
Відповідь:FFFFA002 4294942722 -24574
FFFFA002 – отриманий результат в 16-ій системі числення в
доповняльному коді (-2457410 => -5FFE, оскільки воно відємне, інвертуєм => FFFFA00216);
4294942722 – отриманий результат в 10-ій системі числення в доповняльному коді( FFFFA00216=429494272210);
-24574 – отриманий результат в 10-ій системі числення
Результати виконання програми.
Завдання 1
/
Завдання 2
/
Висновок.
У цій лабораторній роботі ми визначали які явні і неявні перетворення типів відбуватимуться. При обчисленні все зводиться до одного певного типу а тоді вже робиться певне обчислення.