SORU
2 EKİM 2012, Salı


Neden bu kadar karmaşık kod iki güç tarafından imzalı bir tamsayı bölme için duyulur?

Ben VC 10 ile bu kodu derlerken:

DWORD ran = rand();
return ran / 4096;

Bu sökme alıyorum:

299: {
300:    DWORD ran = rand();
  00403940  call        dword ptr [__imp__rand (4050C0h)]  
301:    return ran / 4096;
  00403946  shr         eax,0Ch  
302: }
  00403949  ret

temiz ve özlü ve mantıksal bir vardiya ile iki güç tarafından bir bölümü yerine.

Ama ben bu kodu derlerken:

int ran = rand();
return ran / 4096;

Bu sökme alıyorum:

299: {
300:    int ran = rand();
  00403940  call        dword ptr [__imp__rand (4050C0h)]  
301:    return ran / 4096;
  00403946  cdq  
  00403947  and         edx,0FFFh  
  0040394D  add         eax,edx  
  0040394F  sar         eax,0Ch  
302: }
  00403952  ret

doğru aritmetik bir değişim yapmadan önce bazı manipülasyonlar yapar.

Bu ekstra manipülasyonlar ne gerek var? Neden bir aritmetik shift yeterli değil mi?

CEVAP
2 EKİM 2012, Salı


Neden 2^n tarafından imzalı imzasız bölüm bölüm biraz daha karmaşık ise, çok basit bir şekilde uygulanması olabilir.

unsigned int u;
int v;

u / 4096 u tüm olası değerleri için u >> 12 eşdeğerdir.

v / 4096DEĞİLv >> 12 eşdeğer v < 0, yuvarlama yönü negatif sayılar söz konusu olduğunda karşı bölümü geçmek için farklı zaman bozulur.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • GoProTutorials

    GoProTutoria

    18 NİSAN 2011
  • Kenneth Håkonsen

    Kenneth Håk

    13 Mart 2011
  • Lamborghini

    Lamborghini

    13 Aralık 2005