Jump to page: 1 2 3
Thread overview
Çift yollu otoban! (.sizeof, size t, vs.)
Mar 15, 2012
Salih Dinçer
Mar 15, 2012
Salih Dinçer
Mar 15, 2012
Salih Dinçer
Mar 15, 2012
Salih Dinçer
Mar 16, 2012
Salih Dinçer
Mar 16, 2012
Salih Dinçer
Mar 17, 2012
zafer
Mar 17, 2012
Salih Dinçer
Mar 17, 2012
Salih Dinçer
Mar 19, 2012
zafer
Mar 19, 2012
Salih Dinçer
Mar 19, 2012
zafer
Mar 19, 2012
Salih Dinçer
Mar 20, 2012
zafer
Mar 20, 2012
Salih Dinçer
Mar 20, 2012
Salih Dinçer
Mar 20, 2012
Salih Dinçer
Mar 20, 2012
zafer
Mar 18, 2012
Salih Dinçer
March 15, 2012

Merhaba,

Bugün ilk defa size_t'yi denedim ve 64 bit sistemde bir fark meydana gelir mi diye merak ettim. Bir sorunla karşılaştım ama bunun size_t ile de alakası olmayabilir. Hala öğrenecek ve deneyecek çok şey var...:)

Denediğim ise aşağıdaki kodu 64 bit sistemde derlediğimde 15 değerini almam gerekirken kuramsal açıdan iki katı olan 31 değerini alıyorum. Sonra -m32 ile derlediğimde bu sorun kalmıyor. Demek ki işin sırrı olinde, iki kere rafine... :nuts:

Özele; şaka bir yana bunun anlamı ne?
Alıntı (Salih Dinçer):

>
> import core.stdc.stdio: printf;
>
> int bitBul(size_t arananBitler, ref ubyte[] veri) {
>     int uzunluk = cast(int)arananBitler;
>     size_t kafa, maske = 1;
>
>     for(int i = 1; i <= 64; i++) {
>         maske |= maske << 1;
>         uzunluk >>= 1;
>         if(uzunluk == 0) {
>             maske >>= 1;
>             uzunluk = i;
>             break;
>         } // MSB bitleri 0 olana kadar devam et, önceki duruma dön ve çık
>     } // maske'yi doldur ve uzunluk'tan bir bit çıkar
>
>     for(ubyte b = 0; b < (veri.length * veri.sizeof); b++) {
>         kafa <<= 1;
>     	if((veri[b / veri.sizeof] & (128 >> b % veri.sizeof))!=0) kafa |= 1;
>         kafa &= maske;
>         if (kafa == arananBitler) return b - uzunluk;
>     }
>     return -1;
> }
>
> int main() {
>     // bit >>           8  16  24   32   40   48   56   64 <--ulong
>     ubyte[] veriler = [ 1, 1, 137, 137, 137, 137, 137, 137, 9, 1 ];
>     size_t xKelime = 0b1000_1001; // decimal 137
>     int xKonum = bitBul(xKelime, veriler);
>
>     printf("%lu verisi arandı ", xKelime);
>
>     if(xKonum == -1) {
>         printf("ama bulunamadı!");
>     } else {
>         printf("ve %d numaralı bitden sonra başladığı tespit edildi...:)", xKonum);
>     }
>     printf("\n\nHoşça kalın...\n");
>
>     return 1;
> }
> ```

Teşekkürler...

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
March 15, 2012

Herhalde 64 bit'de değişkenler tıpkı UTF8'de olduğu gibi iki kat olarak ifade edildiği için böyle diyeceğim ama emin olamıyorum. Bu arada aşağıdaki gibi de denedim; ne size_t ile ne de printf kullanmamla alakası var...

   import std.stdio;

   int main() {
       // bit >>           8  16  24   32   40   48   56   64 <--ulong
       ubyte[] veriler = [ 1, 1, 137, 137, 137, 137, 137, 137, 9, 1 ];
       ulong xKelime = 0b1000_1001; // decimal 137
       int xKonum = bitBul(xKelime, veriler);

       writef("%d verisi arandı ", xKelime);

       if(xKonum == -1) {
           write("ama bulunamadı!");
       } else {
           writefln("ve %d numaralı bitden sonra başladığı tespit edildi...:)", xKonum);
       }
       writeln("\nHoşça kalın...");

       return 1;
   }

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 15, 2012

Aslında bu kodda uzunluk, keywordLength demek. Sizeof'u kullanma sebebim ise veri türünün daha büyük değişkenlerde olması durumunda 8 değil de 16, 32, 64 gibi devingen (dynamic) değişkenleri göndermesi. Aslında oraya 128 sabitinde yaptığım gibi durağan (static) bir şekilde 8 koyabilirdik.

Artistik olsun işte...:)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 15, 2012

O zaman sorunun cevabını bulduk, teşekkürler...:)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 15, 2012

Alıntı (Salih Dinçer):

>
>     int uzunluk = cast(int)arananBitler;
> ```

>

Aranan bitlerle uzunluğun ilgisi var mı? 0b1000_1001 aranırken uzunluk 8 olmamalı mı?

Ali

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
March 15, 2012

uzunluk konusunda yanılmışım. Uzunluk anlamında kullanılmıyormuş. ;) (İsimler çok önemlidir.)

Alıntı (Salih Dinçer):

>
>     	if((veri[b / veri.sizeof] & (128 >> b % veri.sizeof))!=0) kafa |= 1;
> ```


Sanırım .sizeof değil de .length olacak.

Ali

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
March 15, 2012

Alıntı (Salih Dinçer):

>

Sizeof'u kullanma sebebim ise veri türünün daha büyük değişkenlerde olması durumunda

Dilimin eleman türünden bahsediyorsun o zaman. Ama veri.sizeof dediğin zaman dilim denen referans nesnesinin büyüklüğünü alıyorsun. O her zaman için bir gösterge ve bir uzunluk üyesinden oluşur. Yani her dilim 32 bitlik sistemlerde 8 bayt, 64 bitlik sistemlerde de 16 bayt olur.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 16, 2012

Sanırım, immutable ve foreach() ile daha iyi oldu! Hiç bir sihirli sayı yok ama büyü devam ediyor...:)

import std.c.stdio: printf;/*
import std.stdio;//*/

   // bit >>           8  16  24   32   40   48   56   64 <--ulong
   uint[] veriler = [ 1, 1, 137, 137, 137, 137, 137, 137, 3, 128 ];
                                                 //   _0011 1000_
   immutable sf = veriler[0].sizeof * 8;   // size of
   immutable sm = 2^^(sf - 1);             // sub mask
   immutable mx = ulong.sizeof * 8;        // data max

   int bitBul(size_t arananBitler, ref size_t[] veri) {
       int uzunluk = cast(int)arananBitler;
       size_t kafa, maske = 1;

       for(int i = 1; i <= mx; i++) {
           maske |= maske << 1;
           uzunluk >>= 1;
           if(uzunluk == 0) {
               maske >>= 1;
               uzunluk = i;
               break;
           } // MSB bitleri 0 olana kadar devam et, önceki duruma dön ve çık
       } // maske'yi doldur ve uzunluk'tan bir bit çıkar

       foreach(bs; 0 .. (veri.length * sf)) {
           kafa <<= 1;
       	if((veri[bs / sf] & (sm >> bs % sf)) != 0) kafa |= 1;
           kafa &= maske;
           if (kafa == arananBitler) return bs - uzunluk;
       }
       return -1;
}

int main() {
   //size_t xKelime = 0b1001_0000; // decimal 144
   size_t xKelime = 0b0111; // decimal 7
   int xKonum = bitBul(xKelime, veriler);

   printf("%lu verisi arandı ", xKelime);
   if (xKonum == -1) {
       printf("ama bulunamadı!");
   } else {
       printf("ve %d numaralı bitden sonra başladığı tespit edildi.", xKonum);
   }
   printf("\n\tVeri türü: %lu bits", sf);
   printf("\n\tVeri genişliği: %lu", sm * 2 - 1);
   printf("\n\tToplam taranan: %lu bits\n", veriler.length * sf);
   printf("\nHoşça kalın...\n");

   return 1;
}

Çıktısı:
Alıntı:

>

'salih@DB-N150-N210-N220:~/d.ders$ ./bitDerle
7 verisi arandı ama bulunamadı!
Veri türü: 32 bits
Veri genişliği: 4294967295
Toplama taranan: 320 bits

Hoşça kalın...'

Deneme imkanınız varsa, bulup bulmadığını görmek için veriler'i, ubyte'a çevirmeniz yeterlidir...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 16, 2012

Notlar:

  1. Değişken isimleri sf gibi kısa seçilip açıklama satırıyla açıklanmak yerine, baştan açık olarak seçilebilir.

  2. .sizeof'un zaten "bayt adedi" gibi bir anlamı var. Bit adedi için de size of demek yanıltıcı olur.

  3. size_t adet gibi, indeks gibi, vs. sayılabilen kavramlara uygundur. Oysa arananBitler ne adet gibi ne de indeks gibi bir kavram. Bence arananBitler için işaretsiz bir tür seçilebilr. Herhalde en uzun olsun diye ulong diyebiliriz.

Veya istersen uint de olur. Buna işlevin karar vermesi gerek. Aslında en iyisi işlevi şablon yapmak ve bu seçimi kullanıcıya bırakmaktır.

Altını çizmek istiyorum: size_t'nin belirli bir ortamda perde arkasında ulong'un takma ismi olması ulong yerine size_t yazma anlamına gelmemeli. Kural şöyle olsun: eğer adet veya indeks gibi bir kavram ise size_t kullanalım.

Buna göre, bitBul'un aslında size_t döndürmesi gerekir. Yoksa şu satırda derleme hatası alıyorum (32 bitlik ortamlarda derleniyordur):

           if (kafa == arananBitler) return bs - uzunluk;

Çünkü ne anlama geldiğini tahmin edemediğim bs size_t türündedir. size_t benim ortamımda ulong'un eşdeğeri olduğundan int'e otomatik olarak dönüşemiyor.

  1. Aynı biçimde veri parametresi de size_t dilimi olmamalı. (Bu konuda da derleme hatası alıyorum.)

  2. Bir önceki değişikliği yaptığımızı kabul ederek, parametreyi 'ref ulong[]' olarak işaretliyorsun. Daha önce söylediğimi tekrarlayacağım: bitBul() gibi bir işlev, aldığı dilimde değişiklik yapmamalıdır çünkü tek amacı bulmaktır. Ayrıca immutable dilimlerle de çağrılabilmelidir. O yüzden parametrenin 'const ulong[]' olması uygundur.

Dilimleri 'ref' olarak işaretlemek ancak asıl dilimde yapısal değişiklikler gerektiği zaman uygundur: eleman eklemek, çıkartmak, vs. Bit bulan bir işlev zaten böyle değişiklikler yapmamalıdır. bulDeğiştir() diye bir işlev olsa tamam.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 16, 2012

Teşekkürler Ali Hocam,

Yazdıklarını bir tek şey dışında anlamadım; o da size_t ile ilgili olanlar. Öncelikle kısaca bu veri türünden ne anladığımı yazmalıyım...

size_t: "Derleyicinin, sistem kaynaklarına ve kodun işleyişine göre karar verdiği (tanımladığı) bir veri türüdür."

Kullanma sebebim ise; aranan veri ile verinin kendisinin değişebilirliliği. Yani veriler[] dizi en küçük ubyte olabilir ama dilediğimizde sınıf veya işlevde değişikliğe gitmeden diğer veri türleri de kullanılmalıdır. İşte bu yüzden yan anlam olarak da şunu zannediyorum:

"...işlevde kullanılırken bağlandığı veri türü ubyte ise temsil eden size_t de ubyte olur" mu?

Ayrıca aranılan veri türü üç bit de olabileceği gibi 64 bit de olabilir. O yüzden size_t kullanmıştım. Yine yukarıdaki gibi aynı mantıkla, xKelime değişkenini ulong olarak tanımlarsam derleyici de size_t'li işlevleri de ulong yapıyor olabilir mi?

Eğer yukarıda şüphelendiğim gibi yanılgı içindeysem size_t'leri tam anlamıyla öğrenene kadar kullanmamalıyım...:)

Sevgiler, saygılar...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

« First   ‹ Prev
1 2 3