Makine Diline Merhaba (10)

Geçen sayıda yazımız makine dilindeki grafik programın BASIC formülasyonunu yapamadan bitmişti. Bu sayıda kaldığımız yerden devam ediyoruz. İşe girişmeden önce biraz düşünüp olayın genel kurallarını meydana çıkaralım. 0'dan 7'ye, 8'den 15'e, 16'dan 23'e vs. olan X-koordinatları aynı byte'ın değişik bitlerine karşılık geliyor. X-belirten sayının alttaki üç bitini dikkate almazsak geri kalanları buradaki gruplar için olduğu gibi aynı. Yani, bellek adresini hesaplarken X-koordinatının en alttaki üç bitini kullanmıyoruz. Bunun için biz bu bitleri silelim. AND komutu, burada imdadımıza yetişecektir.

X AND %11111000

Bu fonksiyonun sonunda, X'in en alttaki üç biti silinmiş halini elde ederiz. BASIC'deki satır şöyle bir şey olacaktır:

PRINT X AND 248

Bir de Y-koordinatı ile, gerekli olan byte'ın adresi arasındaki ilişkiyi bulmaya çalışalım. Y-koordinatı 0 ile 7 arasında ise bu değer doğrudan toplanıyor. Eğer, 8 veya daha büyükse, Y-koordinatının en alttaki üç biti silinmiş halinin 40 katı toplanıyor. Makine dilinde yazmadan önce bir de X-koordinatının büyük değerler alabileceğini hatırlayalım ve ona göre gerekli değişiklikleri yapalım. X değerini XH ve XL adlı iki sayıya bölüştürelim. XH'ın sıfır ile bir değerinden başka bir değer alamayacağı aşikâr. X-koordinatının en yüksek değeri 319 hekzadesimal olarak $13F veriyor. Yani XL $3F, XH $01 değerlerini alıyorlar. Tüm analizimizi bir formülde toplarsak:

PRİNT XH*256-4 (XL AND 248) *
(Y AND 7) * 40*(Y AND 248)

Bu formülü makine diline çevirmemiz gerekiyor. Bu arada, makine dilinde yazacağımız programa koordinatları hangi registerleri kullanarak geçireceğimizi belirleyelim:

Y -> Y-Koordinatı A -> XL-Koordinatı X -> XH-Koordinatı

Program içinde, X-koordinatını saklamak için iki byte'lık bir hafıza bölgesini kullanacağız. Y-koordinatı ile ilgili bilgiyi ise Y-registerinde bırakacağız. İşleme, toplamaları yapabilmek için bir 16 bitlik belleğe daha ihtiyacımız var.

100 — EO XL
 .EÇX
120— — .EÇ SUML-$FC
130 — .EO SUMH - $FO
140 — — .BA $C460
150 — STA XL
160— — STXXH
170 — TYA
180 — — AND : $F8

Gördüğünüz gibi, en sondaki terimden hesaplamaya başladık bile. Fakat, hemen ufak bir sorun çıktı karşımıza. Ana işlem ünitemizin çarpma işlemleri için öngörülmüş komutları mevcut değil. Bu yüzden biz de başka bir yol izleyeceğiz. Biraz gerilere giderek, belli bir değerin içeriğini sola kaydırarak bu sayıyı iki ile çarptığımızı hatırlayalım. Bu kurala uygun olarak, 40'la çarpma olayını parçalara ayıralım:

A*40 A)*2*2*2

İşlemleri bu sırada yürütürsek, akümülatörün önce iki katını, sonra dört katını ve kendisini de toplayarak beş katını elde ederiz. Bu sayıyı da üç kere peş peşe iki katını alırsak en sonunda akümülatörün 40 katı değeri elde ederiz.

190 — STA $FE
200 — STA SUML
210 — LDA
220 — STA SUMH
ASL SUML
240 — ROL SUMH
250 — ASL SUML
260 — ROL SUMH

Bit kaydırma işlemini 16 bit üzerinden yaptık. Bunu, yüksek değerli byte'ı kaydırma için 'ROL' komutunu kullanarak becerdik. Böylece, düşük değerli byte'ın 'ASL' komutu ile kaydırılması sonucu carry'ye çıkan 7'nci bitini, yüksek değerli byte'ı 'ROL' komutuyla kaydırarak 0'ıncı bitin yerine aldık. Gördüğünüz gibi, herhangi bir bilgi kaybına meydan vermeden iki byte'ı bir arada tutup 16 bit üzerinden bit kaydırma işlemi yaptık. Şimdiye kadar yapılan işlemlerle, akünün dört katını elde ettik. Bu değere bir de akünün kendisini toplayarak, akünün beş katı değeri elde edelim.

2710 — CLC
280 — LDA SUML
290 — ADC $FE
300 — STA SUML
310 — LDA SUMH
320 — ADC : 0
330 — STA SUMH

Büyük ihtimalle, çoğunuz SUMH'ye yaptığımız sıfır toplama işleminin ne işe yarayacağını soracaklardır.

Olayı biraz daha yakından inceleyince bu işlemin nedeni açıklık kazanıyor. SUML işlemi sonucunda elde oluşursa, bu durum carry bitinin yardımıyla SUMH'ye iletiliyor. Yani ADC SUMH'nin değerini değiştirmeyecek diye bir şey söz konusu değil. Akünün beş katı değeri bulduktan sonra, üç kere de iki katını alarak hedefimiz olan kırk katı değeri elde edelim:

340 — ASL SUML
350 — ROL SUMH
360 — ASL SUML
370 — ROL SUMH
380 — ASL SUML
390 — ROL SUMH

Böylece, yukarıdaki formülün içinde yer alan en zor ve korkunç terimi hesaplamayı becerdik. Şimdi buna hemen yanındaki terimi hesaplayıp toplayalım.

400— — TYA
410 — AND : 7
420 — CLC
430 — ADC SUML
440 — STA SUML
450 — LDA SUMH
460 — ADC O
470 — STA SUMH

Burada gene yukarıdaki 16 bit üzerinden toplama yaptık. Sekiz bitlik gruplar arasındaki eldeyi de unutmadık tabii. Şimdi, bir de X-koordinatının en alt üç biti silinmiş halini elde ettiğimiz değere toplayalım:

480 — CLC
490 — LDA XL
500 — AND : SF8
510 — ADC SUML
520 — STA SUML
530 — LDA XH
540 — ADC SUMH
550 — STA SUMH

Grafik belleğimizin başlangıç adresi $0000 olmadığı için, biz daha hâlâ bize gerekli olan adresi hesaplayabilmiş değiliz. Başlangıç adresimiz $E000 olduğu için, bu ofset değerini de toplayalım.

— CLC
S70— — LDA : > (SE000)
580 — — ADC SUML
590 — — STA SUML
600 — — LDA ($E000)
610— — ADCSUMH
620— — STA SUMH

Nihayet, SUML/SUMH bizim için gerekli olan adres. Bir de, bu adresteki byte'ın içindeki bit pozisyonunu hesaplamamız gerekiyor. Bu bilgiyi bize, demin hesaplarken kullanmadığımız, X-koordinatının en alttaki üç biti sağlıyor. Bu üç bitin değeri ve bize lazım olan bit numarasını bir tabloda eşleyelim. Böylece arada bir ilişki kurup, bize gerekli olan algoritmayı yaratabiliriz. Bu noktada, gerekli olan bellek elemanının adresini ve bize gerekli olan bitin numarasını biliyoruz. Şimdi bu bite karşılık gelen değeri elde etmemiz gerekiyor. Bunun için değeri '1' olan byte'ın içeriğini (yalnızca sıfır numaralı bit yanık) bit numarası kadar sola kaydırırız.

660 — TAX
670 — LDA 21
680 -SHIFT DEX
690 — BMI OK
700 — — ASL
710 — BNE SHIFT
720 —OK

Akümülatörün içeriğini X-registerinin miktarı kadar sola kaydırdık.

X-koor. Bit no. 0 - 7 6 2 $ 3 4 4 - 3 5 2 6 1 7 0

Yukarıdaki tabloda yeralan değerleri ikili sistemde ele alırsak birbirlerine karşılık gelen rakamlar arasındaki en belirgin ilişkinin bitlerinin ters çevrilmesi olduğunu görürüz. Bilindiği gibi 'EOR' komutu böyle bir işlemi gerçekleştiriyordu.

630 — LDA XL
640 — AND : 7
650 — EOR :7

690'ıncı satırda X-registerinin içeriği bir eksiltiliyor ve hemen arkasından negatif değer elde edilip edilmediği kontrol ediliyor. 710'uncu satırda her ne kadar şartlı dallanma komutu bulunsa da, program burada iken akünün içeriği hiçbir zaman sıfır olmadığı için dallanma olayı daimi olarak gerçekleşiyor. Tüm döngüden çıkış “OK” adlı etiket üzerinden gerçekleşiyor ve döngüden çıkıldığında, bit pozisyonuna karşılık gelen byte değerini elde ediyoruz. Artık ese yazacağımız burada biraz dikkat etmemiz gerekiyor. Şu anda ulaştığımız byte'a daha evvel de bir şeyler yazılmış olabilir. Yani, biz bu adrese doğrudan bir şeyler yazacağımıza buranın içeriğini de dikkate alıp onun üzerinde değişiklikler yapıp öylece yerine yazmamız gerekiyor. Bizim altprogramımızın yapması gereken iş, belli bir koordinatı yakmak olduğuna göre, elde ettiğimiz adresteki elde ettiğimiz numaraya sahip biti yakmamız gerekiyor. Bu olay da, o adresin içeriğini bulduğumuz değerle 'OR' (veya) işleminden geçirmekle olur. Adresimiz iki byte'lık bir göstergeçte bulunduğuna göre indirekt indeksli adresleme tipini kullanmamız için geriye sadece Y-registerini sıfırlamamız kalıyor.

720 —OK LDY :0
130 — ORA (SUML),Y
740 — STA (SUML),Y
750 — RTS

Programımız, mantıksal olarak tümüyle bitti ve bu haliyle işini yapması lazım. Fakat, biz gene de ufak bir noktayı atladığımız için olaylar böyle gelişmeyecek ve programımız doğru olarak çalışmayacaktır. 730'uncu satırda komutu akünün içeriğini $E000'dan $FFFF'e kadar olan bir elemanın içeriği ile 'veya' işlemine sokacaktır. Fakat, normal durumlarda bu bölgede 'KERNAL' romu bulunduğu için, okuma işlemlerinde grafik ram'ine ulaşamayacağız. Yani, 'ORA' komutundan önce 'KERNAL' romunun yerine, grafik ram'inin görünmesini sağlamalıyız. Böyle bir konfigürasyonu seçtiğimizde, işletim sistem romu, bellek haritasında yeralmayacağı için herhangi bir 'interrupt' durumunda bilgisayarınız derhal 'crash' edecektir. Çünkü, interrupt altprogramı işletim sistem romunda yeralmakta. Bu yüzden, sözkonusu konfigürasyonu seçmeden önce interrupt'ları engelleyen flag'ı yakmalıyız. İşimiz bittiğinde, eski konfigürasyonu yerine koyar ve interrupt'lara tekrar izin veririz. Bu arada ek bilgi olarak, belirttiğimiz konfigürasyon değiştirme işleminin $0001 adresli hafıza elemanı vasıtasıyla yapıldığını söyleyelim. Programımızın son kısmını ve BASIC dilinde yazacağımız deneme programını gelecek sayımızda vereceğiz.

BURAK KİPER

Geçen yazımızda modüllerle ana program arasında veri alış-verişi için ikinci yol olarak genel değişkenleri kullanabileceğimizi söyledik. Bu uygulamanın bir sakıncası bulunuyor. Eğer modülle ana program arasında veri alış-verişini PARAMETRE değişkenleri sağlarsa bir bakışta hangi değişkenlerin veri taşıdığını, hangi değişkenlerin etkilendiğini görebiliriz. Ancak veri alış-verişinde genel değişkenler kullanırsak, programımızı yaptıktan bir süre sonra programımıza baktığımızda hangi değişkenlerin modüllerle veri irtibatı sağladığını anlamakta güçlük çekebiliriz. Eğer PARAMETRE değişkenlerini veri alış-verişinde ön kapı olarak düşünürsek genel değişkenlere de veri alış-verişinin arka kapısı diyebiliriz. Genel değişkenleri modülle ana program arasında veri alış-verişinde kullanmak düzensiz bir program hazırlamamıza neden olur. Bu yüzden veri alış-verişlerinde PARAMETRE değişkenlerini kullanmamız iyi bir program hazırlamamız açısından doğru olur. Buna rağmen karşılaşabileceğimiz iki durumda GENEL değişkenleri veri alış-verişinde kullanmak daha faydalı olur: (1) Eğer bir modülü çağırdıktan sonra modüldeki bazı değerleri korumak istiyorsak bölgesel değişkenlerle amacımıza ulaşamayız. Modüller her çağrıldıklarında bölgesel değişkenler için özel bir hafıza alanı ayrılır. Modülden çıkıldığında modüle ait bölgesel değişkenlere yüklenmiş değerler de kaybedilir. Modül tekrar çağrıldığında yeni bir hafıza alanı ayrılır. Kalıcı olmasını istediğimiz bir değer varsa GENEL değişken kullanmamız gerekir. (2) Bazan birçok modül aynı veri yapısı üstünde çalışır, mesela büyük bir tablo üstünde. Böyle bir durumda birçok modül tarafından kullanılan değişkeni GENEL değişken olarak tanımlamak daha uygun olacaktır. Bu yazımızda anlattıklarımızı pratik olarak uygulayabilmek için geçen sayıda yayınlanan Program Döküm Eki'ndeki iki programı inceleyebilirsiniz. Genel değişkenleri kullanmamız için iki durumun mevcut olduğunu söylemiştik. İlk programımız böyle bir duruma örnek olabilir. Bu programımızda rastgele sayılar üreten bir fonksiyon tanımlanıyor. Tanımladığımız fonksiyon kullanılarak bilgisayar 0 ile 100 arasında değişen sayılar tutarak bu sayıyı bulmanızı istiyor. Rastgele sayı üreten fonksiyonumuz pek profesyonel bir fonksiyon değil ama birçok oyun tipi uygulamada işinizi görür. Fonksiyonumuza çekirdek bir rakam gerekiyor. Fonksiyonumuz aldığı çekirdek sayıyı kullanarak yeni bir çekirdek sayı üretiyor. Yeni üretilen çekirdek sayı bir sonraki hesaplamada kullanılıyor. Çekirdek sayıyı taşıyan değer GENEL değişken olarak tanımlandığından fonksiyon her çağrıldığında çekirdek sayının bir evvelki değeri kaybolmuyor. 0 ile 100 arasında bir sayı elde etmek istediğimiz için çekirdek sayımızı 100 ile çarpıp elde edilen sonucun tam sayı kısmına 1 eklemek yeterli oluyor. İkinci programımız ise bir hesap makinesini taklit ediyor. Hesaplatmak istediğiniz işlemi belirli bir yapıya göre girmeniz gerekiyor. Aksi takdirde hata mesajı ile karşılaşabilirsiniz. RECURSION (kendi kendini çağırma)

Bir alt program veya fonksiyon başka bir alt program veya fonksiyonu çağırabilir. Eğer bir alt program veya fonksiyon kendisini çağırırsa buna RECURSIVE (kendisini çağıran) alt program veya fonksiyon adını veririz. Recursive şekilde programlamayı, döngü tipi programlama yerine kullanabiliriz. Gerçi döngü tipi programlama ile karşılaştırıldığında daha fazla zaman ve hafıza harcanmasına neden olan bu uygulama bazen döngü tipi ile çok zor yapılacak programların çok kolay bir şekilde gerçekleştirilmesini sağlar.

Döngülerde olduğu gibi recursive uygulama da kendiliğinden duramaz, bu yüzden programa ne zaman durması gerektiğini bildiren bir komut eklememiz gerekir. Recursive bir alt program inceleyelim:

PROCEDURE TERS(N:
GER);
VAR
VERİ:CHAR;
BEGİN
İF 1 THEN
BEGİN
READ(VERİ);
WRITE(VERİ);
END
ELSE
BEGIN
ERS(N-İ);
END
END;
IİNTE-

TERS, alt programımız N değişkeninin değeri kadar harften oluşan bir kelimeyi tersten yazacak. Eğer bilgisayar

TERS(5);

şeklinde bir komutla karşılaşırsa girilen beş harf tersten yazılacak. Alt programımızda yeralan,

IF N-1 THEN

komutu recursive uygulamanın durma şartını sağlamak amacı ile kullanıldı. Eğer durdurma şartı yanlışsa (N değişkeninin değeri 1'den büyükse) recursive adım uygulanacak. READ komutu ile yeni karakteri okuyup, N-1 değeri ile aynı alt programı tekrar çağıracağız. Okunmuş olan karakter ise WRITE komutu işlenemediğinden daha sonra yazılır. Şimdi bilgisayarın N-3 değeri ile bu alt programı çalıştırmaya başladığında nasıl bir yol izlediğini görelim:

N-3 değeri ile TERS alt programı çağır. VERİ değişkenine ilk karakteri oku. N-2 değeri ile TERS alt programını çağır. İkinci karakteri VERİ değişkenine oku,

N-1 değeri ile TERS alt programını çağır. Üçüncü karakteri VERİ değişkenine oku. Üçüncü karakteri ekrana yaz. Üçüncü çağırıştan geri dön. İkinci karakteri ekrana yaz. İkinci çağırıştan geri dön. İlk karakteri ekrana yaz. İlk çağırıştan geri dön.

Yukarıda gördüğümüz gibi,

TERS(3)

verdiğimizde TERS alt programı her seferinde değişik değerlerle olmak üzere üç kere çağırılıyor.

Kalıcı olmasını istediğimiz bir değer varsa GENEL değişken kullanmamız gerekir.

Alt programdan dönüş alt programın çağırılma sırasının tersi yönde gerçekleşir, yani son çağırıştan ilk olarak döneriz.

BASİT VERİ TİPLERİ

Bilgisayar programlamasını iki başlık altında toplayabiliriz: (1) İşlenecek verilerin düzenlenmesi (2) İşlemlerin gerçekleştirilmesi Şimdiye kadar işlemlerin gerçekleştirilmesini sağlayacak komutlar üzerinde durduk. Yazımızın bu bölümünde ise işlenecek verilerin düzenlenmesi üzerinde duracağız. Pascal'da veriler, veri tipleri sayesinde düzenlenir. Şimdiye kadar programlarımızda veri tipi olarak REAL, CHAR ve BOOLEAN veri tiplerini kullandık. Veri tiplerini, BASİT, YAPISAL ve BELİRTEÇ tipler şeklinde üç sınıfa ayırabiliriz. BASİT veri tipindeki bir değişkene sadece bir tek değer verilebilir. YAPISAL veri tipindeki değişkenin taşıdığı değer daha ufak parçalara ayrılabilir. BELİRTEÇ veri tipini bilgisayarın hafızasında yeralan verilerin yerinin belirtilmesinde kullanırız. Yazımızın bu kısmında sadece BASİT veri tipine değineceğiz.

ORDİNAL VERİ TİPLERİ

İlk olarak ordinal kelimesinin ne ifade ettiğini açıklamaya çalışalım. Kelimemiz, arkasından gelen, birbirini izleyen anlamına geliyor. Buna bir örnek verelim:

1234... A BC-D TRUE FALSE

BASİT veri tipi ordinal veri tipi ile REAL veri tipi olmak üzere ikiye ayrılıyor. CHAR ve BOOLEAN ordinal veri tipine giriyor.

Veri Tipi Tanımlanması

PASCAL, programcılara kendi bünyesinde bulunan veri tiplerinin dışında veri tipleri tanımlanmasına izin verir. Buna örnek vermek için ilk olarak bildiğimiz veri tiplerine farklı isimler verelim. Daha sonraki PASCAL'da bulunan veri tiplerinden başka veri tipi tanımlamayı göreceğiz.

TYPE
TAMSAYI - İNTEGER;
ONDALIK - REAL;
KARAR BOOLEAN;
HARF - CHAR;

Artık kendi veri tiplerimize sahip olduğumuza göre bunları kullanarak değişkenler tanımlayalım:

VAR
TAMSAYI;
X,Y,Z : KARAR;
A : HARF;

Bilgisayar bu tanımlamaları işlediğinde I,J,K değişkenleri INTEGER veri tipindeki değerlere, X,Y,Z değişkenleri REAL veri tipindeki değerlere, P,Q,R değişkenleri BOOLEAN veri tipindeki değerlere, A değişkeni CHAR veri tipindeki değere sahip olacaklar. Yeni bir veri tipi tanımlamak için TYPE komutundan sonra yeni veri tipinin ismini yazıyor araya eşit koyup, yeni veri tipini tanımlıyoruz.

Bir PASCAL programının bildirimlerinde yeni veri tipi tanımlama CONST bildiriminden sonra gelir. Veri tipi tanımlamadan sonra ise DEĞİŞKEN bildirimleri gelir. PASCAL'da bir bloğun başlangıcında yer alan değişik tanımlama ve bildirimler aşağıdaki sıra ile olmalıdır:

(1) CONST tanımlamaları (2) TYPE tanımlamaları (3) VAR bildirimleri (4) FUNCTION veya PROCEDURE bildirimleri

Her programda bunların hepsi olması gerekmez ancak olduklarında bu sırayı izlemek zorundadırlar. PASCAL'ın sıralı şekilde bildirmek şartı ile yeni ORDİNAL veri tipleri tanımlamanıza izin verdiğini söylemiştik. Bunu bir örnekle görelim:

TYPE
GUN (PA, PT, SA,
CA, PE, CU, CT);
RENK - (KIRMIZI,
TURUNCU, SARI,
YESİL, — MAVI,
MOR);
SATRANÇ - (KALE, AT, FIL,
SAH, — VEZİR,
PIYON);
AYLAR - (OCA, SUB,
MAR, NIS, MAY,
HAZ, TEM, AĞU,
EYL, EKİ, KAS,
ARA);
NOT -(FDCBA),;

Mesela GUN veri tipi PA, PT, SA, CA, PE, CU, CT belirteçleri tarafından tanımlanmış yedi değer içeriyor. Listedeki belirteçlerin sırası çok önemli, zaten öyle olmasa bunlar ORDİNAL veri tipi olamazlardı. Sıralı olmaları sayesinde hangi değerin öncelik sırasına sahip olduğunu biliyoruz. Mesela PA, PT'den evvel geliyor. CT'si CU'dan sonra geliyor. Eğer G değişkenini,

VAR
G: GÜN;

şeklinde tanımlarsak,

D:-PA
ve

şeklinde eşitlemeler doğru olur.

Bildiğimiz BOOLEAN veri tipini, BOOLEAN = (FALSE, TRUE);

şeklinde tanımlayabiliriz. Ancak bu tanımlama PASCAL tarafından yapıldığı için bizim tekrar böyle bir tanımlama yapmamız gereksiz olur. Bir programda tanımladığımız bir veri tipinde yer alan belirteci tanımlayacağımız başka bir veri tipinde kullanamayız:

TYPE
SATRANC — (KALE,AT,FIL);
HAYVAN - (FIL,AT,DEVE);

şeklindeki bildirim yanlış olurdu. Çünkü AT ve FIL belirteçleri her iki veri tipinde de yer alıyor. Kendi hazırlayacağımız veri tipine sahip olacak bir değişkeni TYPE kullanmadan tanımlayabiliriz:

VAR
A : (KIS, ILKBAHAR, YAZ,
SONBAHAR);

Eğer TYPE kullansaydık:

TYPE
MEVSİM - (KIS, ILKBAHAR,
YAZ, SONBAHAR);
VAR
A: MEVSİM;

şeklinde tanımlardık. Her ORDİNAL veri tipi için bu tipin bir alt kümesi sayılabilecek yeni veri tipleri tanımlayabiliriz:

ISGUNU — PT..CU;

GUN veri tipinin bir alt kümesi olup, PT, SA, CA, PE, CU değerlerine sahiptir. GUN veri tipi ile tüm yapabildiğiniz işlemleri ISGUNU veri tipi ile de yapabilirsiniz. Tek fark ISGUNU veri tipinin belirlenen değerler içinde yer almasıdır. Buna bir örnek verelim:

VAR
K:ISGUNU;
BEĞİN
END.

komutu her zaman geçerlidir, çünkü K değişkenin değeri I değişkeninin alabileceği değerler arasında bulunur. Ama I komutu sadece I değişkeninin değeri PT ile CU değerleri arasında bulunuyorsa doğrudur.

Ordinal Veri Tiplerinde İşlemler

Ordinal veri tipindeki değerler için belirli bir sıra vardır. INTEGER veri tipi için bildiğimiz sayısal sıra, BOOLEAN veri tipi için önce FALSE sonra TRUE. Kendi tanımladığımız veri tipleri içinse yaptığımız listedeki sıra geçerlidir. Bütün değerler birbirini izlediği için;

bu işlemcileri Ordinal veri tiplerinde kullanabiliriz. Bunları bir örnekle görelim:

İFADE DEĞER

PA < PE TRUE KIRMIZI > MAVİ FALSE MART > NİSAN FALSE

Gelecek yazımızda Ordinal veri tiplerinde kullanılan bazı fonksiyonları göreceğiz. Şimdilik hoşça kalın. O