Loading...

Берилгендердин типтеринин калыптанышы

    Ар бир базалык берилгендер тиби эстутумдан белгилүү бир байт санын ээлейт. Бул маалыматтардын ар кандай типтерин камтыган операцияларга чектөө киргизет. Төмөнкү мисалды карап көрөлү:

int a = 4;

byte b = a; // ! Ката

Бул коддо биз катага туш болобуз. Byte тиби да, int тиби да бүтүн сандарды билдирет. Мындан тышкары, byte түрүндөгү өзгөрмөгө ыйгарылган a өзгөрмөнүн мааниси byte түрүнүн маанилеринин диапазонунда (-128ден 127ге чейин). Бирок, биз компиляция учурунда катага туш болобуз. Анткени бул учурда биз 4 байтты ээлеген айрым маалыматтарды бир байт гана ээлеген өзгөрмөгө ыйгарууга аракет кылып жатабыз.

 

Бирок, программа мындай өзгөртүүнү талап кылышы мүмкүн. Бул учурда, түрүн өзгөртүү операциясын колдонуу керек (операция ()):

 

int a = 4;

byte b = (byte) a;  // типти өзгөртүү: int түрүнөн byte түрүнө

System.out.println(b); // 4

 

Типти бир типтен экинчи типке өткөрүү операциясы кашаанын ичинде маанинин тибине өтүүчү тибин көрсөтүүнү камтыйт. Мисалы, (byte)а операциясында int тибиндеги маалыматтарды byte тибине которуп алабыз. Натыйжада, биз byte тибинин маанисин алабыз.

 

Ачык(явные) жана жашыруун(неявные) типтердин калыптанышы

Бир эле операцияга ар кандай типтеги маалыматтар тартылганда, типти өзгөртүү операциясын колдонуу дайыма эле зарыл боло бербейт. Трансформациянын кээ бир түрлөрү кыйыр түрдө автоматтык түрдө аткарылат.

 

Автоматтык түрдө типтердин калыптанышы

Сүрөттөгү жебелер кайсы типке которуулар автоматтык түрдө аткарыла тургандыгын көрсөтүп турат. Үзүктүү жебелер тактыкты жоготуу менен автоматтык которууларды көрсөтөт.

 

Кеңейтүү трансформациялары (widening) эч кандай көйгөйсүз автоматтык түрдө аткарылат - алар объекттин эс тутумдагы чагылдырылышын кеңейтет. Мисалы:

byte b = 7;

int d = b;  // byteтан intке которуу

Бул учурда эстутумда 1 байтты ээлеген байт түрүнүн мааниси 4 байтты ээлеген int типине кеңейтилет.

 

Узартуу автоматтык трансформациялар төмөнкү чынжырлар менен көрсөтүлөт:

byte -> short -> int -> long

int -> double

short -> float -> double

char -> int

 

Тактыкты жоготуу менен аткарылган автоматтык трансформациялар

Кээ бир трансформациялар автоматтык түрдө бирдей бит тереңдиктеги маалымат түрлөрүнүн ортосунда, ал тургай чоңураак бит тереңдиктеги маалымат тибинен кичине бит туурасы бар маалымат түрүнө чейин автоматтык түрдө аткарылышы мүмкүн. Бул төмөнкү трансформациялар чынжырлары: int -> float, long -> float жана long -> double. Алар катасыз чыгарылат, бирок биз трансформациялоо учурунда маалыматтын жоголушуна туш болушубуз мүмкүн.

 

Мисалы:

int a = 2147483647;

float b = a;            // intтен float тибине өткөрүү

System.out.println(b);  // 2.14748365E9

 

Ачык трансформациялоо

Калган бардык учурларда оригиналдуу типтердин трансформациясы.Эреже катары, бул чоңураак бит тереңдиктеги түрдөн азыраак бит тереңдиктеги ооруларга чейин кыскаруу (narrowing) болуп саналат:

long a = 4;

int b = (int) a;

 

 

Трансформация учурунда маалыматтарды жоготуу

Ачык трансформацияларды колдонгондо, биз маалымат жоготууга туш болушубуз мүмкүн. Мисалы, төмөнкү коддо бизде эч кандай көйгөй болбойт:

int a = 5;

byte b = (byte) a;

System.out.println(b);      // 5

 

5 саны байт түрүнүн маанилеринин диапазонунда жакшы, ошондуктан конверсиядан кийин b өзгөрмөсү 5ке барабар болот. Бирок төмөнкү учурда эмне болот:

int a = 258;

byte b = (byte) a;

System.out.println(b);      // 2

 

Натыйжада 2 саны болот. Бул учурда 258 саны байт түрү үчүн диапазондон тышкары (-128ден 127ге чейин), андыктан маани кыскартылат. Эмне үчүн натыйжа так саны 2?

 

258ге барабар болгон a саны экилик системада 00000000 00000000 00000001 00000010 га барабар болот. Байттык маанилер эстутумда болгону 8 битти ээлейт. Демек, intтин бинардык көрүнүшү оң 8 цифрага, башкача айтканда 00000010го кыскартылат, ал ондук санда 2 санын берет.

 

Рационалдык сандарды бүтүн сандарга кыскартуу

Калкыма чекиттин маанилерин бүтүн санга которууда бөлчөк бөлүгү кыскартылат:

double a = 56.9898;

int b = (int)a;

Бул жерде b мааниси 56 болот, бирок 57 56,9898ге жакыныраак болот. Мындай окуяларды болтурбоо үчүн Java Math библиотекасында жайгашкан тегеректөө функциясын колдонушуңуз керек:

double a = 56.9898;

int b = (int)Math.round(a);