Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

C18 rand() Sorunu

Başlatan Tagli, 05 Ocak 2011, 10:07:27

Tagli

0'dan 3'e kadar (0, 1, 2, 3) rastgele bir tam sayıya ihtiyacım var. Bunun için rand() % 4 ifadesini kullanıyorum. Sorun şu ki hep 1 ve 3 değerleri dönüyor. Ve sıralı olarak, yani 1, 3, 1, 3, 1, 3.... şeklinde. Bunu çözmek için ne yapabilirim? Deneme amaçlı olarak rand() % 5 yazdığımda düzgün değerler döndüğünü gördüm ama bu şekliyle işimi görmüyor.

Seed'i değiştirdiğimde dönen değerler değişiyor ancak yine iki sayı arasında gidip geliyor, 0 ve 2 gibi mesela.
Gökçe Tağlıoğlu

X-Fi

rastgele sayı elde etmek için timer0 registerını okuyabilirsiniz durdurulamayan timerdır çünkü bunu nerede kullanmıyorsunuz işlemci rand() komutunu nasıl oluşturuyor donanımsal böyle bir yapı yok bildiğim kadarıyla.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

Tagli

Garip bir matematiksel fonksiyon ile oluşturuyor galiba. Başta bir seed değeri veriliyor, srand(322) mesela. Sonra fonksiyon her çağrılışında bir f fonksiyonu f(n), f(n+1) gibi değerlerle çağrılıyor. Sanırım seed değeri de fonksiyonun içindeki bir parametre. Öyle ki fonksiyon aslında her seed değeri için sırayla aynı sayıları üretiyor, bu yüzden de "pseudo random" olarak ifade ediliyor. Söz konusu fonksiyon garip birşey olduğundan f(n), f(n+1), f(n+2) gibi değerler birbirinden alakasız gibi, yani rastgele görünüyor.

Wikipedia'da örnekleri var.

Aslında timer kullanarak da üretebilirim rastgele sayı ama algoritmanın dönüş zamanı hakkında bir fikrim yok. Hep aynı sürede dönüyorsa bu sorun olabilir. Yazdığım kod dışarıdan input almıyor sayılır. Bu yüzden süre konusunda şüphelerim var. Yine de bir çözüm bulamazsam onu deneyeceğim.
Gökçe Tağlıoğlu

X-Fi

hocam dışarıdan rastgele bir referans olmadan hiçbir formül random sayı üretemez C18 bunu ne mantıkla yaptı bilmiyorum ama matematikte birbirini tekrarlıyan formüller hep aynı sayıyı almak zorunda bencede siz timer ile yapmalısınız timer0 başlangıç değeri randomdur reset attırıp farklı değerler okumanız mümkün veya VDI(valid data indicator) pin çıkışlı ek donanımlardan faydalanabilirsiniz.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

muuzoo

rand fonksiyonu sahte rastgele sayılar üretir. Programı her başlattığınızda aynı sayılar tekrar üretilecektir. Bu yüzden genelde srand fonksiyonu bir çekirdek değer ile çağrılır ve bu değer ile rand fonksiyonunu besleyerek değer üretir. Fakat her seferinde bir besleme değerine gerek olacaktır. Normalde bilgisayar üzerinde kod yazarken şöyle bir kullanım vardır

srand(time(NULL));


Bu sayede her seferinde srand için değer girmeye gerek kalmaz. Zaman bilgisini çekirdek değer olarak kullanıp bir sayı üretir. Pic üzerinde de sizin ihtiyacınız olan şey raslantısal bir çekirdek değeri almaktır. Eğer projenizde rtc varsa oradan alacağınız değeri kullanabilirsiniz. Bana kalırsa en güzel çözüm bu olur çünkü programa her seferinde farklı değerlerin girileceği garanti edilir. Diğer bir yöntem de timer çalıştırıp içeriğini okumak olabilir ama bu yöntemle ilgili şüphelerim var. Programın çalışma hızı aynı olursa acaba bir yerden sonra timer üzerinden hep aynı değerleri okur mu? Bir diğer yöntem de belki sıcaklık sensörü ya da adc gibi bir kaynaktan sık değişen düşük bitleri kaynak olarak kullanıp srand fonksiyonunu beslemek olabilir.
gunluk.muuzoo.gen.tr - Kişisel karalamalarım...

Tagli

Her seferinde aynı sayıların üretilmesi benim için sorun değil. Sorun bu sayıların % 4 işleminden sonra hep aynı 2 değeri vermeleri. Yani örneğin programı her çalıştırdığımda aynı 03213021130210023 gibi bir seri üretse benim için sorun yok. Ama şu anda hep 131313131313 serisini üretiyor. Seed'i değiştirince de mesela 202020202020 üretiyor.
Gökçe Tağlıoğlu

mufitsozen

#6
Alıntı yapılan: Tagli - 05 Ocak 2011, 11:36:58
Her seferinde aynı sayıların üretilmesi benim için sorun değil. Sorun bu sayıların % 4 işleminden sonra hep aynı 2 değeri vermeleri. Yani örneğin programı her çalıştırdığımda aynı 03213021130210023 gibi bir seri üretse benim için sorun yok. Ama şu anda hep 131313131313 serisini üretiyor. Seed'i değiştirince de mesela 202020202020 üretiyor.

bunun nedeni, size gelen degeri "%" operatoru ile cok kisitli bir bolgeye zorlamaniz. Zaten bu tur (hesaplama ile) rastgele sayi ureten sistemler genellikle bir muddet sonra tekrarlar meydana getirirler. O yuzden gercekten rastgele bir sayi dizini uretebilmek oldukca zordur (derlersede inanmayiniz :-) bkz: Mersenne twister). Modulo operatorunu kullanarak siz rand() fonksiyonunun kendi sinirlari icerisinde "normal dagilima" uydurmaya calistigi sayi dizininin sadece bir bolgesini kullanrak bu dagilimi bozuyorsunuz. Bunun icin modulo islemi yerine ust seviyedeki birleri kullanir yada daha iyisi belli araliklari test edersiniz. bkz asagidaki ornek

Eger kullaniminizda rand() fonksiyonu kullanimi kabul edilebilir bir method ise, "%" operatoru kullanmak yerine baska yollardan bu degerleri uretin.

or: eger rand sonucunda 0-99 arasinda deger cikiyorsa (ornegin dedim:-)) 0-24 arasini 0, 25-49 arasini 1, 50-74 arasini  2 ve son olarak 75-99 arasinida 3 olarak kullanin. ( mesela y = x>74 ? 3 : x>49 ? 2 : x>25 ? 1: 0; )

ama bu beni kesmez derseniz, hardware kullanarak bir rand sayi ureteci yapmak denenebilir.

Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

Tagli

Fikir için teşekkürler. Ancak TMR0L % 4 ifadesi işimi gördü gibi gözüküyor. İlerde sorun çıkarırsa yöntem değiştirebilirim.

Her ne kadar sorun çözülmüş de olsa derleyiciden kaynaklanan bu durum genel olarak kafamı kurcalamaya devam ediyor. rand() komutunu özgürce kullanamamak sinir bozucu bir durum. Bu konuda deneyimi olan arkadaşlar deneyimlerini paylaşırlarsa sevinirim.
Gökçe Tağlıoğlu

ferit06


Sayın Tagli,

tam 1  yıl önce benzer  problemi ben de Protonda yaşamıştım. Sizin de katkılarınız ile sorunumu çözmüştüm.

https://www.picproje.org/index.php/topic,24398.0.html