Tam Sürümünü Görmek İçin : Even & Odd (çift ve tek)
bize girilen belii bi aralıktaki sayıları tek ve çift olarak ayırmamız ve sonra da bu ayırdığımız tekleri ve çiftleri toplamamız istendi ve tabikide bunu ekranda yazdırmamız.
yani output;
örnk:
Enter an interval: 5 15
Even-----Odd
--6--------5
--8--------7
--10-------9
--12-------11
--14-------13
---------15
Total Even:50
Total Odd :60
boyle bi cıktı almamız istenioo
bunu nasıl yapabiliriz acıklayarak anlatabilirseniz cok memnun olurum
şimdiden tesekkur ederim
#include <iostream>
using namespace std;
int main()
{
int ilksayi = 5;
int ikincisayi = 15;
int tek = 0;
int cift = 0;
for( int i = ilksayi+1; i < ikincisayi; i++)
{
if( i & int(1) == 0x01 )
{
cout << "tek"<<endl;
tek++;
}
else
{
cout << "cift"<<endl;
cift++;
}
}
cout << "toplam tek sayi: " << tek << endl;
cout << "toplam cift sayi: "<< cift << endl;
return 0;
}
peki bu tek sayıları ayrı ve çift sayıları ayrı nasıl toplicazz? hem ayrıca 0x01 anlamı nedir?
eğer bir sayı tekse en sağdaki rakam daima birdir,
int(1) demek, 31 tane sıfır yanına bir tane 1 rakamı demek
&, eğer her iki rakamda 1 ise bir sonucu üretir,
eğer bir rakam 31 tane sıfır ardına bir tane 1 dizesinin oluşturduğu bir rakam ile & işlecine tutulursa sonuç da sadece 32. rakamın değeri ortada kalır, 32. rakam 1 ise sonuç 1, 0 ise sonuç 0'dır.
eğer bir rakam tek ise daimi olarak en sağdaki rakamın( yada loworder bit, yada en sağdaki bit) değeri daima 1 dir.
dolayısıyla belirtilen işlemin sonucu 1 ise rakam tekdir.
ör:
1010 0100 0101 1101 1110 1011 ( bu elimizdeki sayı olsun )
0000 0000 0000 0000 0000 0001 ( buda int(1) in karşılığı
sonuç:
0000 0000 0000 0000 0000 0001
yani rakam tek.
if( i & int(1) == 0x01 )
atg hocayı tanıyor galiba , mesaj göndermiş.:4:
if( i % 2 == 1 ) de iş görür.
2'de bıraktığı kalan bir ise tekdir.
Euclides
19/11/2005, 23:42
if( i & int(1) == 0x01 )
atg hocayı tanıyor galiba , mesaj göndermiş.:4:
bence atg'nin iyi optimize edilmiş bir yöntem, and her zaman div'den hızlıdır. (15-20 kat kadar :D)
if( i % 2 == 1 ) de iş görür.
2'de bıraktığı kalan bir ise tekdir.
hatta buda :P :P :P :P :P :P :D
if(((x >> 1) << 1) ^ x)
{
printf("Tek");
}else{
printf("Çift");
}
acehreli
20/11/2005, 05:16
atg, 1'in tUrU zaten int'tir; int(1)'in bir katkisi olmuyor. Ayrica int'in 32 bit oldugu yaygindir ama kesin degildir :)
marp, 0x01'in ne oldugunu ogretmeden boyle bir soru sormalarina sasirdim... Yani kesinlikle kullanilmasi gerekmiyor ama sabit sayilarin nasil yazildiklarinin ogretilmesini beklerdim.
Euclides, kaydirma isleclerini kullanirken x unsigned olsa iyi... :) Ama signed bir turle calisirken ve eger deger sifirdan kucukse, saga kaydirmanin etkisi derleyiciye birakilmistir (implementation defined), sola kaydirmanin etkisi ise belirsiz (unspecified) birakilmistir. Ama tabii yine de herhalde her ortamda calisir :)
Ali
atg, 1'in tUrU zaten int'tir; int(1)'in bir katkisi olmuyor. Ayrica int'in 32 bit oldugu yaygindir ama kesin degildir :)
Bunu söyleyeceğinizi biliyordum :)
marp, 0x01'in ne oldugunu ogretmeden boyle bir soru sormalarina sasirdim... Yani kesinlikle kullanilmasi gerekmiyor ama sabit sayilarin nasil yazildiklarinin ogretilmesini beklerdim.
Bence bu arkadaşımız matematik bölümünde okuyor(tahmin), ve C, onlar için bir tür yan ders, anlaşılan o ki; sanırım arkadaşımız bu dersi pek sevmiyor ve buda dersleri takip etmemesi için -görece- geçerli bir neden, keza peki bu tek sayıları ayrı ve çift sayıları ayrı nasıl toplicazz şeklinde bir soru yöneltmesi(çözümü çok basit bir soru çünkü) olan biteni açığa vermeye yetiyor.(tabi bunlarda birer tahmin, aslı nedir bilemem)
myavuzselim
20/11/2005, 14:34
Bu gibi optimizasyonlari cogu derleyicinin kendi yaptigi soyleniyor. Ben de gcc ile denedim:
unsigned int func(unsigned int n) {
return n % 2;
}
gcc -S a.c:
func:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
andl $1, %eax
popl %ebp
ret
gcc bu optimizasyonu yapmis.
Hatta x * 8, x * 64 gibi durumlari da optimize ediyor.
Euclides
20/11/2005, 16:11
Bu gibi optimizasyonlari cogu derleyicinin kendi yaptigi soyleniyor. Ben de gcc ile denedim:
...../code/.....
gcc bu optimizasyonu yapmis.
Hatta x * 8, x * 64 gibi durumlari da optimize ediyor.
En sonunda yapmışler demek :D Fakat ben olsam derleyicime güvenmezdim -O1, -O2, -O3 :P ile denedim sonuç hep aynı
(GCC 4.0.1)
Kötü kod....
int abc(int x,int y,int w)
{
x = y/w + x/w;
return x;
}
00000000 55 push ebp
00000001 89E5 mov ebp,esp
00000003 53 push ebx
00000004 51 push ecx
00000005 8B450C mov eax,[ebp+0xc]
00000008 99 cdq
00000009 F77D10 idiv dword [ebp+0x10]
0000000C 89C3 mov ebx,eax
0000000E 8B4508 mov eax,[ebp+0x8]
00000011 99 cdq
00000012 F77D10 idiv dword [ebp+0x10]
00000015 8D0403 lea eax,[ebx+eax]
00000018 5A pop edx
00000019 5B pop ebx
0000001A C9 leave
0000001B C3 ret
İyi kod...
int abc(int x,int y,int w)
{
x = (y+x)/w;
return x;
}
00000000 55 push ebp
00000001 89E5 mov ebp,esp
00000003 8B450C mov eax,[ebp+0xc]
00000006 034508 add eax,[ebp+0x8]
00000009 99 cdq
0000000A F77D10 idiv dword [ebp+0x10]
0000000D C9 leave
0000000E C3 ret
Eğer bu tip iyileştirmeler hakkında daha örnek görmek istersen bu kitaba bakabilirsin Hacker's Delight (http://www.amazon.com/gp/product/0201914654/104-1540673-5028726?v=glance&n=283155&n=507846&s=books&v=glance)
acehreli
20/11/2005, 17:29
Euclides, gcc gosterdigin iyilestirmeyi yapamaz cunku y+x'in sonucunun her zaman icin bir tasmaya neden olup olmayacagini bilemez. Tasma olmasa bile, C'nin tamsayi bolmelerde kalani goz ardi etmesi nedeniyle de zaten iki islem birbirinin esdegeri degildir.
Ornegin x ve y 1, w da 2 ise; "kotu kod"un sonucu 0, "iyi kod"un sonucu 1 cikiyor.
Ama dedigini anliyorum tabii ki; bazi yerlerde iyilestirmeyi elle yapmak gerekebilir.
Ali
Euclides
21/11/2005, 01:29
evt. haklısın, teşekkürler acehreli; sanırım artık yaşlanıyorum :)...
Forum Yazılımı : vBulletin v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.