Makine Dilinde Rastlantısal Sayılar
DEVRİM KORKMAZ bilir. Yani beş yüz rastlantısal sayı arasında yüz adet sayısına karşılık yalnızca iki adet “iki” elde edebilirsiniz. Tabii ki çok düzgün bir dağılım elde edilebilecek yöntemler bulunabilir, ama burada bu kadar derinlemesine bir araştırma yapmaya niyetimiz yok.
Kendi Zarınızı Atın
Makine dilinde program yaparken, genel olarak rastlantısal sayılar üretecek bir rutine erişim yapamazsınız. Tabii ki ROM'da bulunan rutinleri kullanabilirsiniz, ama bunu yapamayacağınız zamanlar da olacaktır. Makine dilinde çok uzun sürelerde bile kendini tekrar etmeyen, bunun yanında oldukça iyi bir dağılıma sahip sayılar üretebilecek yöntemler var tabii ki. O kadar derinlemesine bir araştırma yapmamamıza rağmen, oldukça işinize yarayacak bir yöntem olduğunu düşünüyoruz. Tekniği incelemeden önce biraz daha temel oluşturalım isterseniz. Şekil 1'e bir göz atarsanız, değeri yalnızca 0 veya 1 olabilecek olan hücreleri kullanarak nasıl 0 veya 1 sayılarını rastlantısal olarak elde edebileceğimizi görebilirsiniz. Her hane kendi değerini bir yandaki haneye iletirken, ikinci ve beşinci hanelerindeki değerler EOR'lanıp (iki sayı eşitse sonuç 0, farklıysa sonuç 1 olur. Ör: EOR 1-0) ilk haneye iletilir. Bu şekilde üretilen 0 ve 1 sayıları oldukça tesadüfi bir şekilde oluşur. Burada yalnızca beş hane olduğu için kısa bir süre sonra 0 ve 1 sırası kendini kısa sürede tekrar etmeye başlar. Ama 30 hanelik bir sistem kullansaydık 0 ve 1 rutininin kendini tekrar etmeye başlaması için tam (2^30)-1 tane değer okumamız gerekecekti. Saniyede 1000 sayı okuyabilseydik, tam 300 saat sonra kendini tekrarlamaya başlayacaktı bu seri. Ama hangi kutulara EOR işleminin uygulanacağı gene de bir problem olarak kalmaktadır. Bu kutuları seçmek için bir matematik teoremi bulunmaktadır tabii ki. Ama bu teorem çok karmaşık olduğu için burada anlatmayacağız. 34 kutuya kadar olan sistemlerde hangi kutulara bu işlemin uygulanacağını Şekil 2'de bulunan tablodan görebilirsiniz. Bu tür sistemler elektronikte de sıkça kullanılmaktadır. “İyi de ikili sistemlerden bana ne? Ben ondalık sayılarla çalışmak istiyorum!” diyebilirsiniz tabii ki. Ama bu sistemi, her kutucuğa 0'dan 9'a kadar olan sayıları koyup kullanabilirsiniz. Tabii ki o zaman EOR komutunu kullanamazsınız. Ama EOR işlemi aslında MOD 2'de yapılmış bir toplamayla aynı sonucu verir. Yani iki değeri toplayıp 2'ye böldüğünüzde, kalan sizin istediğiniz sayı olacaktır. Yani kutulara 0'dan 9'a kadar olan sayıları yerleştirirseniz MOD 10'da bir toplama yapmanız yeterlidir (6+7=3 MOD 10). Son bir şey daha: Her kutucuğa koyacağınız sayının maksimum değeri, kutu sayısından az olmamalıdır. Eğer bu kuralı çiğnerseniz maksimum uzunlukta kendini tekrarlamama özelliğinden yararlanamazsınız. Yani 8 kutunuz varsa, her kutuya maksimum 7 değerini verebilirsiniz.
< *t <
Şekil-1: Rastlantısal sayı üretmek için kullanılan sistem.
Yazılımla da Yapalım mı?
Elektronikte işlerin nasıl yürüdüğüne baktığımıza göre, sıra yazılıma geldi sanırım. 30 kutulu ikili sayıların 300 saatten önce kendini tekrarlamadığını söylemiştik. Eğer 30 kutulu ve her kutuda 0'dan 9'a kadar sayılar olan bir sistem kursaydık ve saniyede bin değer okuyabilseydik, bu sistem kendini tekrarlamaya başlamadan önce tam 36,533,877 yıl geçmesi gerekecekti. Yanlış okumadınız, otuzaltı milyon yıl dedim. Tabii ki hepimiz bu rastlantısal sayıları bilgisayarımızda yaratmak istiyoruz. Bilgisayarımızı yukarıda anlattığım kutu sistemini kullanması için programlamak oldukça kolay. Her kutucuğa bir bayt ayırırsak, kutular maksimum 255 değerini alabilir ki bu değer bizim ihtiyacımız olanın kat kat üzerindedir. Kutuları çalıştırmadan önce her birine gerekli aralıkta bir sayı vermemiz gerekmektedir. Eğer tüm kutuları sıfırla doldurursak her seferinde oldukça rastlantısal olan sıfır değerini alırız. Programı yaparken Şekil 2'de bulunan kutuları birbirine gerekli MOD'da eklemeyi unutmayın. Bu yazılım kutularının gerçekten çalışması için şöyle bir mantık yürütmeliyiz: İlk olarak gerekli kutuları toplarız ve bu toplamanın değerini geçici bir yere yazarız. Daha sonra en son kutudan bir öncekini en son kutuya alıp, bu şekilde aşağı doğru inerek her kutunun değerini bir sonrakine yazarız. Son olarak da geçici yerde sakladığımız değeri ilk kutuya yazarsak bir tur tamamlamış oluruz. Herhangi bir kutudaki değeri çıktı olarak kullanabilirsiniz ama her okuyuşunuzda aynı kutuyu kullanmaya özen gösterin.
Şekil-2: Maksimum sayıda rastlantısal sayı elde etmek için birbirine eklenmesi gereken kutular bunlardır.
Programlarımız da Var
1. programımız (RND1) 21 kutulu, MOD 10'da çalışan bir makine dili program. Programı kullanmadan önce bu 21 kutuyu 10'dan küçük değerlerle doldurmayı unutmayın. Program 2 ise program 1'i belleğe yükleyen, daha sonra da çalışmasını size gösteren bir BASIC programı. Bu programı çalıştırdığınızda ilk olarak 21 basamaklı bir sayı girmeniz istenir. Daha sonra bu basamaklar kullanılarak üretilen tesadüfi sayılar ekrana yazılırlar. RND1 aslında bu tür bir uygulamayı yazmanın ne kadar kolay olduğunu anlatmak için yapılmış bir programdır. Program 3, yani RND2 kutuların 16'sını doldurmuştur ve yalnızca iki beşini size sorar. Daha sonra ilk sayı üretilmeden önce
2560 kere kutu kaydırılır ve bu sayede 'orijinal sayıların ortadan kaybolması sağlanır. Programı ilk kullandığınızda $2341'den çalıştırın, daha sonra $234A'ya sıçrayarak yeni rastlantısal sayınızı elde edin. Program 4, program 2'nin yaptığının aynısını program 3 için yapan bir BA-SIC programıdır. Bu iki program aynı şekilde çalışır ve 0-9 arası bir değer verir çıktı olarak. Eğer istediğiniz sayının basamak sayısı 1'den fazlaysa belli ku-
program 1:
taban — $232b
kutu21- $2340
kutu2 - $232d
kutul - $232c
geç — - $232a
*2$2341
kaydır clc ;başlangıç
Ida kutu2l1
ade kutu2 ;kutuları ekle
emp #10
bee geçici şa<l0: zaten MOD 10
sbe #10 şa za MOD 10
geçici sta — geç ;geçici bellekte sakla
ldx #20 ;kayacak kutu sayısı
döngü Ida taban,x ;bu kutuyu...
sta — taban4İ,x ;...buraya al
dex ;bir alttaki kutu
cpx #0 kaldi mı?
bne döngü ;hayır, devam
lda geç ;geçici değeri al
sta — kutul ;kutul'e koy
rts
program3:
taban — $232b
kutu21 — $2340
kutu2 —$232d
kütul > $232c
geç — $232a
bayrak — $2329
yüksek — $2328
başlangıç değerleri----
.byte 3,5,9,4,7,1,4,6,3,2,0,5,7,4,9,8
ilk lda #0 şilk ayarlamalar için giriş
sta yüksek — ;sayacın yüksek baytı
sta bayrak şbayrağı temizle
tay şsayacın alçak baytı
kaydır clc şyeni sayı hesapla, giriş
ida kutu21
ade kutu2
emp #10
bec geçici şa<İ0: zaten MOD 10
sbe #10 şa za MOD 10
geçici sta geç ş;kaydırma bitene kadar sakla
ldx #20 sayısı
döngü Ida taban,x — ;bu kutuyu...
sta taban4İ,x ;buraya çek
dex kutu
emp #0 şbitti mi?
bne döngü şhayır, devam
lda geç şgeçici değeri al
sat kutul kutuya yaz
Ida bayrak
emp #$ff ş;bayrak havada mı?
bne döngü2 — ;hayır, 2560 kere kaydır
rts
döngü2 iny artır
cpy #0
bne kaydır 30 değil, devam
inc yüksek ;0, yüksek sayacı artır
lda yüksek
emp #10 ;kaydırmalar bitti mi?
bne kaydır ş;hayır, kaydır.
Ida #$ff
sta bayrak şevet, bayrağı kaldır
jmp kaydır. — ;bitti
PROGRAM ADI
» PROGRAM 2
tuları okuyarak 21'e kadar basamaklı sayılar elde edebilirsiniz. Gördüğünüz gibi tesadüfi sayılar elde etmek oldukça kolay. Bütün yapmanız gereken buradakine benzer programlar yaratmak. Bu programlar kendini tekrarlama konusunda işinizi halledebilecek kadar iyidirler.
00100 REM RNDİ-BASIC YÜKLEYİCİ *DEMÜ <032>
00110 FOR A-0 TO 35:READ B:POKE <159>
00120 NEXT <130>
00200 REM ----- RNDi DEM0------ <080>
00210 PRİNT "21 BASAMAKLI BİR SAYI GİRİN"
<043>
00220 FOR Az0 TO 20 <ı43>
00230 GET K$:1F THEN 230 <156>
00240 <159>
00250 POKE <255>
00260 PRİNT CHR$(147);J$
00270 NEXT <026>
00280 SYS 9025:REM -$2341 <063>
00290 PRINT PEEK(9004);:REM -$232C
00300 GOTO 280 <110>
00310 REM <118>
01000 DATA 24,173,64,35,109,45,35,201 <023>
Ol1OLO DATA 10,144,2,233,10,141,42,35 <244A>
01020 DATA 162,20,189,43,35,157,44,35 <204>
01030 DATA 202,224,0,208,245,173,42,35 <002>
01040 DATA 141,44,35,96 <1BO>
PROGRAM ADI : PROGRAMA
00100 REM RND2-BASİC YÜKLEYİCİ *DEMO <096>
00110 FOR TO 90:READ B:POKE 90094*A,B <163>
00120 NEXT <130>
“00200 REM ----- RND2 <088>
00210 "5 BASAMAKLI BIR SAYI GİRİN" <099>
00220 FOR A-0 TO 4 <096>
00230 GET K$:1F K$-"" THEN 230 <156>
00240 <159>
00250 POKE VAL(K$) <255>
00260 PRİNT <227>
00270 NEXT <026>
00280 SYS 9025:REM -$2341 <063>
00290 SYS 9034:REM -$234A <045>
00300 PRİNT PEEK(9004);:REM -$232C
00310 290 <136>
00999 REM <043>
01000 DATA 3,5,9,4,7,1,4,6 <070>
01010 DATA 3,2,0,5,7,4,9,8 <0B4>
01020 DATA 169;,0,141,40,35,141,41,35 <24A9>
01030 DATA 168,24,173,64,35,109,45,35 <025>
01040 DATA 201,10,144,2,233,10,141,42 <101>
01050 DATA 35,162,20,189,43,35,157,44 <225>
01060 DATA 35,202,224,0,208,245,173,42 <080>
01070 DATA 35,141,44,35,173,41,35,201 <098>
01080 DATA 255,208,1,96,200,192,0,208 <068>
01090 DATA 208,238,40,35,173,40,35,201 <109>
01100 DATA 10,208,198,169,255,141,41,35 — <05B>
01110 DATA 76,74,35 <090>