tam sayının basmaklarını bulmak?

Başlatan picmanya, 20 Eylül 2011, 21:10:58

picmanya

unsigned char sayi, onlar, birler = 0;

sayi = 32;
onlar = (sayi / 10);
birler = (sayi % 10);

iki basamaklı tam sayının basamaklarını böyle buluyorum.

bu sayı 4 haneli tam sayı olduğunda basamaklarını en etkin şekilde nasıl bulabilirim.
etkinden kasıt; program yazımı uzun olsada önemli değil.
önemli olan işlemcide - programda en az gecikme ile işi başarmalıyım.
nasıl bir yöntem önerebilirsiniz?

normal bölme ve modüler bölme işlemi, işlemcide en uzun gecikme ile uygulanabilen komutlar oluyor.
bu yöntemden farklı bir çözüm varmı? onu öğrenmek istiyorum.

zakbay

sayi = 3210;
binler = (sayi/1000)%10;
yuzler = (sayi/100)%10;
onlar = (sayi / 10)%10;
birler = (sayi % 10);


bu şekilde bulabilirsin bundan daha etkin nasıl bulunur bilmiyorum
Tek dostum çalışmak...

JKramer

   unsigned int16 sayi=3210;
   unsigned int8 binler=0;
   unsigned int8 yuzler=0;
   unsigned int8 onlar=0;
   unsigned int8 birler=0;

   while(sayi>999)
   {
      sayi-=1000;
      binler++;
   }
   
   while(sayi>99)
   {
      sayi-=100;
      yuzler++;
   }
   
   while(sayi>9)
   {
      sayi-=10;
      onlar++;
   }
   
   birler=sayi;

iyildirim

8 bitlik pic için JKramer'in kodunu kullanırdım.

16 bitlik piclerde C30 ile örnekte ki koda benzer birşey kullanıyorum. 4 digit için 60-65 clock civarı işlem zamanı yeterli oluyor.
        binler = __builtin_divud((long)sayi , 1000u );
        sayi -= binler * 1000u;

        yuzler = __builtin_divud((long)sayi , 100u );
        sayi -= yuzler * 100u;
        
        onlar = __builtin_divud((long)sayi , 10u );
        sayi -= onlar * 10u;
        
        birler = sayi;



picmanya

#4
int sayi, binler, yuzler, onlar, birler = 0;

sayi = 3223;                           //sayi değişkenine, 0 ile 9999 arasında, bu değerlerde dahil, herhangibir tam sayı değer atanıyor.
binler = (sayi/1000)%10;
yuzler = (sayi/100)%10;
onlar = (sayi / 10)%10;
birler = (sayi % 10);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int sayi, binler, yuzler, onlar, birler = 0;

sayi = 3223;                           //sayi değişkenine, 0 ile 9999 arasında, bu değerlerde dahil, herhangibir tam sayı değer atanıyor.
binler = sayi /1000;
sayi = sayi - (1000 * binler);
yuzler = sayi / 100;
sayi = sayi - (100 * yuzler);
onler = sayi / 10;
sayi = sayi - (10 * onlar);
birler = sayi;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

binler = __builtin_divud((long)sayi , 1000u );
sayi -= binler * 1000u;
yuzler = __builtin_divud((long)sayi , 100u );
sayi -= yuzler * 100u;       
onlar = __builtin_divud((long)sayi , 10u );
sayi -= onlar * 10u;       
birler = sayi;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

ilk yöntem zakbay'ın yöntemi, ikinci yöntem benim yöntemim, üçüncü yöntem iyildirim'in yöntemi
son yöntemde, yanlış değilsem değişkenler yine tamsayı olarak tanımlanıyor galiba. gerçi long ifadeside geçiyor.

bu yöntemlerin C30 altında, dsPIC30F ve dsPIC33F işlemcilerinde ne kadar zamanda-saykılda yürütüldüğünü öğrenmek istiyorum. bunun için kodları MPLAB IDE altında yazıp, C30 için derleyip ASM kodlarını ürettirebiliyorum. ASM kodlarından tek tek her bir komutun işlem saykılını hesaplamakdan farklı olarak bu işi daha kolay yapabileceğim bir metod varmı?

MPLAB IDE nin program satırlarının kaç saykılda yürütüldüğü, IDE altında bir yerde otomatik olarak yazılıp veriliyormu?


düzeltme:
unsigned __builtin_divud(const unsigned long num, const unsigned den);
tanım bu şekilde yapılmış. üçüncü programda long tür den değişken tanımlanıyor olmalı.
builtin yapısını daha önce hiç kullanmadım ve bilmiyorum. bayada fazla çeşitli builtin kullanımı varmış.

http://ww1.microchip.com/downloads/en/devicedoc/51284h.pdf
sayfa 147 ve sonrası açıklanmış. ama bana uzak bir konu.

ilaveten:
ilk iki programcıkda, sayi değişkenine sıfır veya sıfırdan küçük bir negatif işaretli değer, yanlışlık sonucu atanırsa, bir hata meydana geliyor olmalı. bur da işlemci nasıl davranır?

Erol YILMAZ

#5
int sayi, binler, yuzler, onlar, birler = 0;

sayi = 3223;                           //sayi değişkenine, 0 ile 9999 arasında, bu değerlerde dahil, herhangibir tam sayı değer atanıyor.
binler = sayi /1000;
sayi = sayi - (1000 * binler);
yuzler = sayi / 100;
sayi = sayi - (100 * yuzler);
onlar = sayi / 10;
sayi = sayi - (10 * onlar);
birler = sayi;


bu PIC16'da 1030 cycle tutuyor...

sayi = 3223;                           //sayi değişkenine, 0 ile 9999 arasında, bu değerlerde dahil, herhangibir tam sayı değer atanıyor.
binler = (sayi/1000)%10;
yuzler = (sayi/100)%10;
onlar = (sayi / 10)%10;
birler = (sayi % 10);


Bu da PIC16 da 3546 cycle tutuyor..

picmanya

#6
Hocam programcıkların ne saykıl tuttuğu bir yerde otomatik yazıyor mu?
kendinizmi hesaplıyorsunuz?

ilk iki program fazla clock tutuyor. ama C30 için 1000 clock falan tutacağını sanmam.
bölme 16 clock luk bir işlem ve en uzun tutanı diye biliyorum.

bu durumda iyildirim'in verdiği 65 cloc hıza, ilk iki program yatişemez gibi duruyor.

daha etkin farklı bir yöntem varsa, direkt asm yazımıda olsa, öğrenmek isterim. sonucda C30 içine asm kod da gömülüyor.

Erol YILMAZ

Picmanya sana oltayı da vereyim, kendi balığını kendin tut...


IDE : MPLAB 8.73
C Compiler : Hi-Tech PICC 9.65 PL1
Simulasyon yazılımı: MPLAB SIM (Debugger bölümünden seçiyoruz)
Ölçüm aracı : Stopwatch

Derledikten sonra, F8 ile adım adım ilerleyip kodun başında Stopwatch'u sıfırlıyoruz.
Bahsi geçen kod bitince geçen cycle sayısına bakıyoruz.

picmanya

#8
bu simülasyon adını bugünlerde sık sık duymaya başladım. ona bir göz atmam gerekecek galiba.

simülasyona bulaşma dan, C30 kod derleme ve ASM30 kod karşılıklarını otomatik üreterek, burdan clock işlem zamanlarına bakmak bir şekilde mümkünmüdür?
ben şu anda ASM30 kod satırlarının, komutlarının tuttuğu clock zamanını parmakla toplayarak hesaplıyorum.

bunu simülasyonsuz, derleme sonucunda veren bir ayar yada yer mevcutmudur?

Erol YILMAZ

Simulasyondan çekinmeye gerek yok.
Evet birçok problemi var ama böyle basit konularda rahatlıkla kullanılabilir.

CLR

Alıntı yapılan: picmanya - 21 Eylül 2011, 10:40:07
Hocam programcıkların ne saykıl tuttuğu bir yerde otomatik yazıyor mu?
kendinizmi hesaplıyorsunuz?

ilk iki program fazla clock tutuyor. ama C30 için 1000 clock falan tutacağını sanmam.
bölme 16 clock luk bir işlem ve en uzun tutanı diye biliyorum.

bu durumda iyildirim'in verdiği 65 cloc hıza, ilk iki program yatişemez gibi duruyor.

daha etkin farklı bir yöntem varsa, direkt asm yazımıda olsa, öğrenmek isterim. sonucda C30 içine asm kod da gömülüyor.

Asm komutları içinde doğrudan bölme komutları var onlarla kolayca yapabilirsin. Asm30 komut listesini incele, göreceksin ama C30 ile yaparsan senin yerine o aynı komutları kullanacak, 20-30 asm satırında bahsettiğin bölme işlemlerini sonuçlandıracaktır. 
Knowledge and Experience are Power

OptimusPrime

sayı=8765;

birler=sayı%10; sayı/=10;
onlar=sayı%10; sayı/=10;
yüzler=sayı%10; sayı/=10;
binler=sayı;


genelde bunu kullanırım.

aldığın cevaplar için bir cycle tablosu oluşturabilirsen bizde hangi kodun daha hızlı çalıştığını öğrenmiş oluruz...
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

z

Alıntı yapılan: picmanya - 21 Eylül 2011, 10:40:07
....programcıkların ne saykıl tuttuğu bir yerde otomatik yazıyor mu?
kendinizmi hesaplıyorsunuz?

Simülasyon fikir verir, asm kodlar da fikir verir fakat her ikisi de uğraştırıcı olur.

Debuggerla senkronize çalışan ve rutinlerin ne kadar zaman aldığını söyleyen yazılımlar var. Fakat en kolayı rutinin girişinde port pinlerinden birini high yapıp, rutinden çıkıldığında bu port pinini low yapacak kısa kod eklentisi sayesinde scopla bu pini gözlemlemen.

Bu rutini test amaçlı olarak sonsuz döngüde sürekli olarak çağırıp pinde oluşan sinyalin süresine bakmak daha da doğru sonuç verir.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Alıntı yapılan: OptimusPrime - 21 Eylül 2011, 12:24:36
sayı=8765;

birler=sayı%10; sayı/=10;
onlar=sayı%10; sayı/=10;
yüzler=sayı%10; sayı/=10;
binler=sayı;


genelde bunu kullanırım.

aldığın cevaplar için bir cycle tablosu oluşturabilirsen bizde hangi kodun daha hızlı çalıştığını öğrenmiş oluruz...

Adama % ile bölme yaptırıyorsun. Ardından / ile bir bölme daha yaptırıyorsun. Derleyici kodun çaresine bakıp niyetini anlarmı bilmiyorum ama yöntem bu yüzden güzel değil.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

OptimusPrime

evet adamı hakkaten çok uğraştırmışız. kusura bakmasın. zaten ben adamı en az bu yorar da dememiştim o yüzden benden günah gitti.

sizde bu adamları daha az yoran bir kod var mı acaba veya diğer arkadaşların yazdığı kodlara da yorum yapabilecek misiniz?

Bu adamların hali ne olacak çok merak ediyorum...
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||