Picproje Elektronik Sitesi

DERLEYİCİLER => PIC C => Konuyu başlatan: FxDev - 10 Mayıs 2011, 23:40:17

Başlık: C'de Temel Fonksiyonların İşleyişleri
Gönderen: FxDev - 10 Mayıs 2011, 23:40:17
Hepimiz C ve C dilinde math.h kütüphanesini bir kere de olsa kullanmışızdır. Hepimizin bildiği üzere içinde bulunan sin cos ve sqrt gibi işlemler işimizi oldukça kolaylaştırmakta. Peki bu kod yapısı örneğin 3'ün karekökünü bana nasıl veriyor? Ya da bir sayının sin cos'unu nasıl hesaplıyor. İçeriğindeki mantık nedir?
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Erol YILMAZ - 11 Mayıs 2011, 00:55:40
Numerik Hesaplama Yöntemleri kullanılıyor.
Misal karekök için birçok yöntem varmış...

http://en.wikipedia.org/wiki/Methods_of_computing_square_roots

Araştırdıkça konu hoşuma gitmeye başladı.
Özellikle Newton matematik için ciddi gelişimler yapmış. Bkn. Türev ve İntegral :)

Tamsayı Karekök Algoritması:
http://www.embedded-systems.com/98/9802fe2.htm

Diğerlerini bulan arkadaşların çözümlerini de bekleriz.
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Tagli - 11 Mayıs 2011, 01:03:34
Trigonometrik fonksiyonlar için tablo kullanılıyor olabilir. Bunları ekleyince program hafızası kullanımında ciddi bir artış gözleniyor. Emin değilim ama.

Ayrıca, fonksiyonları kullanmak bir kenara, floating point ile işlem yapmak bile ayrı bir mesele. Floating point ile dört işlem yapılırken bile arka planda bir dolu iş yapılıyor. C18'de bu alt işlemlerin her birine karşılık gelen ayrı asm dosyaları var.

Fonksiyonlarla ilgili kodların bir kısmını C18'in klasörü içinde bulmak mümkün ama benim bulduklarım sistemin nasıl çalıştığı hakkında tam bir bilgi vermiyor. Belki de ben görememişimdir.
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Erol YILMAZ - 11 Mayıs 2011, 01:20:24
Trigonometrik ifadelerin de açılımı var,
Gördüğüm kadarı ile gayet kolay hesaplabiliyor.
Float sayı ile hesabı gerektiğinden uzun süren işlemler olabilir.

http://www.pdfill.com/example/Numerical_Methods.pdf

Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: serdararikan - 11 Mayıs 2011, 01:40:22
aradığınız cevap Taylor serisi olabilirmi?

http://dotancohen.com/eng/taylor-sine.php
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: z - 11 Mayıs 2011, 02:27:33
Hesaplayicilarda sikca kullanilan algoritma Cordic algoritmasidir.

Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: muuzoo - 11 Mayıs 2011, 03:46:14
Bu konuyu araştırırken çok ilginç bir kod buldum. Yöntem aslında 1990'larda geliştirilmiş. 1999 yılında Quake III oyun motorunda kullanılmış, 2002,2003 yıllarında unix forumlarına düşümüş fakat 2005 yılında quake3 kodlarının paylaşılması ile patlama yapmış. Bu kadar bilgiden sonra önce kaynak sayfa :

http://en.wikipedia.org/wiki/Fast_inverse_square_root

Ve yöntem. En başlarda olay pek anlaşılamamış, zaten kod açıklamalarından göreceksiniz  ;) Tüm olay şu sihirli sayıda : 0x5f3759df

float Q_rsqrt( float number )
{
        long i;
        float x2, y;
        const float threehalfs = 1.5F;

        x2 = number * 0.5F;
        y  = number;
        i  = * ( long * ) &y;                       // evil floating point bit level hacking [sic]
        i  = 0x5f3759df - ( i >> 1 );               // what the fuck? [sic]
        y  = * ( float * ) &i;
        y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//    y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

        return y;
}


32bit fp için 0x5f3759df
64bit fp için 0x5fe6eb50c7aa19f9.
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: NaMcHo - 11 Mayıs 2011, 10:39:39
y  = * ( float * ) &i   şurdaki yapılan işlem nedir?   stm32 nin kütüphanelerindede   *(x *) şeklinde çok tanımlama var burdada görünce dayanamadım sorim dedim.
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: jackal183 - 11 Mayıs 2011, 10:42:18
trigonometrik işlemlerin çözümü için, seriye açılımları kullanılıyor, seriye açılımları birçoğunuz üniversitede mat2 dersinde görmüşsünüzdür, derleyiciler hangi seriye açılımı kullanıyor bilmiyorum ama arkadaşın da söylediği gibi taylor serisi kullanılan yöntemlerden biridir, bunun dışında mclourin serisi de vardır
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Tagli - 11 Mayıs 2011, 11:02:29
Alıntı yapılan: NaMcHo - 11 Mayıs 2011, 10:39:39
y  = * ( float * ) &i   şurdaki yapılan işlem nedir?   stm32 nin kütüphanelerindede   *(x *) şeklinde çok tanımlama var burdada görünce dayanamadım sorim dedim.
O değişkenin adresinde tutulan değeri tam sayı olarak değil float olarak değerlendir demek istiyor.

Yanlış anlamadıysam, üzerinde bit işlemleri yapabilmek için öncelikle float y'nin long olduğunu varsayıp kaydırma yapmış. Sonra çıkan sonucu tekrar derleyiciye "bu aslında bir float'tır" diye göstermiş.
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Klein - 11 Mayıs 2011, 19:04:37
Alıntı yapılan: NaMcHo - 11 Mayıs 2011, 10:39:39
y  = * ( float * ) &i   şurdaki yapılan işlem nedir?   stm32 nin kütüphanelerindede   *(x *) şeklinde çok tanımlama var burdada görünce dayanamadım sorim dedim.

burada ilk yıldız , i nin gösterdiği adreste bulunan veriyi al ifadesidir. eğer * koymasaydı alacağımız değer  i nin adresi  olacaktı.

float ifadesi Tagli'nin dediği gibi tip dönüşüm ifadesidir. Sonucu float olaak değerlendir demek.  float ifadesinin sağındaki * ise   sonucun da bir pointer ile aktarılacağını ifade ediyor.

aşağıdaki kod parçacıkları eeproma float değer yazma ve okuma işi yaparlar.  bu örnek belki durumu biraz daha iyi açıklar.

void ee_read_float(unsigned int addr , float *floatptr){
unsigned char edata;
unsigned int I;
for(I=0;I<4;I++){
edata=ee_read_byte(I+addr);
  *((unsigned char *)floatptr+I) = edata;
}
}

void ee_write_long(unsigned int addr , long int *longptr){
unsigned char edata;
unsigned int I;
for(I=0;I<4;I++){
edata = *((unsigned char *)longptr+I);
ee_write_byte(addr+I,edata);
}
}

Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Klein - 11 Mayıs 2011, 19:16:42
yukarıdakialgoritmada anlamadığım bir şey var.


const float threehalfs = 1.5F;
x2 = number * 0.5F;


buradaki 1.5F ve 0.5F  daha önceden  #define ile tanımlanmış sabitler mi? yoksa benim bilmediğim bir jargon mu?
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Tagli - 11 Mayıs 2011, 19:23:33
Yani aslında yapılan iş bir çeşit derleyiciyi kandırmak. O alanlarda aslında float saklanıyor ama sen derleyiciye "Hayır, bu bir long. Sen işlemini ona göre yap." diyorsun. Elbette ilgili sayıyı long gibi alıp üzerinde işlem yaparsan, float değerine çok garip şeyler olabilir  ;). Yukarıdaki kodu garip yapan şey de bu. Adam float sayıyı long gibi gösterip üzerinde garip işlemler yapmış...

Dikkat edilmesi gereken şey casting diye bilinen bu işlemin, değişken üzerinde değil, onun pointer'ı üzerinde yapılıyor olması. float değerini long'a cast etseydi, fazla kafa karıştırmazdı. Örneğin 5.256 ifadesi 5 olurdu. Ama pointer'ı cast etmesi bambaşka birşey.

Klein, bildiğim kadarıyla sonlarında bulunan F, o değerlerin float tipinde olduğunu gösteriyor derleyiciye. Varsayılan değer nedir bilmiyorum. Bilgisayarda genelde double oluyor, yani hiçbir şey eklemezsen sonuna. float olarak alınmasını istiyorsan özellikle F ekliyorsun sonuna. Bu tür şeyler genelde gerekmiyor ama bazen hiç ummadığın yerlerde kıllık çıkarabiliyor. Şu başlığı (https://www.picproje.org/index.php/topic,32584.0.html) bir incele.
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: yamak - 11 Mayıs 2011, 19:56:22
int main(void)
{
  long i=5;
  float y;
  y=*(float*)&i;
  printf("%f",y);
    getch();

arkadaşlar yukarıdaki kodu denemek için şöyle küçük bir program yazdım sonucunu 0.0fakat derleyici sonucu 0.000 olarak verdi nedeni nedir acaba?
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Tagli - 11 Mayıs 2011, 20:04:55
Wikipedia'daki başlığı (http://en.wikipedia.org/wiki/Single_precision) bir incele (kodu bilgisayarda yazdığını varsayıyorum).

(http://upload.wikimedia.org/wikipedia/commons/thumb/d/d2/Float_example.svg/590px-Float_example.svg.png)

(http://upload.wikimedia.org/math/c/0/2/c02c37523ae1acfd150420c1e2355ba6.png)

Şimdi, kutuların içinde "00000000 00000000 00000000 00000101" olduğunu varsay, yani 5.

Olay kafamda yanlış canlanmadıysa, bunu float gibi düşündüğünde çok küçük bir sayı çıkacak. Bu yüzden ekrana 0 olarak basılıyor olabilir.
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Klein - 11 Mayıs 2011, 20:28:56
Alıntı yapılan: yamak - 11 Mayıs 2011, 19:56:22
int main(void)
{
  long i=5;
  float y;
  y=*(float*)&i;
  printf("%f",y);
    getch();

arkadaşlar yukarıdaki kodu denemek için şöyle küçük bir program yazdım sonucunu 0.0fakat derleyici sonucu 0.000 olarak verdi nedeni nedir acaba?

Daha önceki mesajımda konuyu tam olarak açıklayamadım sanırım. Sebebi ise  sonucu float olaak değerlendir demiş olmam. Aslında bu tanım tam olarak doğru değil.  Eğer  float ifadesinin sağında  * olmasaydı , tanım doğru olacaktı.  Doğru tanım  float pointer olarak değerlendir olacak. 
Şöyle:

eğer  :
y= *(float) &i   demiş olsaydık:
i şaretçisinin gösterdiği adresteki değeri  , float olarak y değişkenine atacaktık.  burada derleyici bir tip dönüşümü işlemi uygulayacaktı. ve sonucu doğru görecektin.
fakat biz dedik ki ,  sonucu float pointer ile gönder.  Bu durumda  sayıyı bir float dönüşüm işlemine tabi tutmadı. Sadece  aldığu 4 baytlık değeri , aynen  y değişkenine aktardı.
Float sayılar  tamsayılar gibi değildir.   tamsayılarda int ve char arasındaki fark sadece  kapladıkları alan farkıdır.
Örneğin: int tipi bir değişkenin içeriği  135 ise  , bu değişkenin ilk baytının içeriği 135 ikinci baytının içeriği ise 0 dır. bu durumda  taşmamak kaydıyla  int veya char tipi değişkenlerin içeriğini birbiri arasında takas edebiliriz.
Ama float sayılarda durum farklı.   Float sayının ilk baytına 135 sayısını yazarsak , float olarak anlamsız bir sayı elde ederiz.

Bu sebeple , yukarıdaki kodda  long sayının içeriğini4 bayt olarak doğrudan  float sayının içine yazdığımız için sonuçta anlamsız bir sayı elde ettik.   bazı printf kütüphaneleri anlamsız float sayıları 0 olarak gösterir. Bu sebeple  0 olarak görmüş olabilirsiniz.
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: NaMcHo - 11 Mayıs 2011, 20:43:59
Alıntı yapılan: Klein - 11 Mayıs 2011, 19:04:37
Alıntı yapılan: NaMcHo - 11 Mayıs 2011, 10:39:39
y  = * ( float * ) &i   şurdaki yapılan işlem nedir?   stm32 nin kütüphanelerindede   *(x *) şeklinde çok tanımlama var burdada görünce dayanamadım sorim dedim.

burada ilk yıldız , i nin gösterdiği adreste bulunan veriyi al ifadesidir. eğer * koymasaydı alacağımız değer  i nin adresi  olacaktı.

float ifadesi Tagli'nin dediği gibi tip dönüşüm ifadesidir. Sonucu float olaak değerlendir demek.  float ifadesinin sağındaki * ise   sonucun da bir pointer ile aktarılacağını ifade ediyor.

Şuda doğru olurmu y pointer olarak tanımlanmış olsa
y=*(float)&i  ile y  = * ( float * ) &i bunlar birbirine denkmidir?2. koddaki y ise float
1.işlemde float pointer olan y ye i'nin adresindeki değeri float olarak gönderiyoruz
2.işlemde ise i'nin adresi içindeki değeri float pointer olarak  float y değişkenine gönderiyoruz

2. yazdığımdan pek bişey anlayamadım şuanda :)
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Klein - 11 Mayıs 2011, 20:46:39
Yok ikisi aynı ifade değil.  Bir önceki mesajda farkı açıkladım.  Sorun ilk açıklamadaki eksik bir ifadeden kaynaklanıyor.
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: yamak - 11 Mayıs 2011, 23:49:19
Alıntı YapDaha önceki mesajımda konuyu tam olarak açıklayamadım sanırım. Sebebi ise  sonucu float olaak değerlendir demiş olmam. Aslında bu tanım tam olarak doğru değil.  Eğer  float ifadesinin sağında  * olmasaydı , tanım doğru olacaktı.  Doğru tanım  float pointer olarak değerlendir olacak. 
Şöyle:

eğer  :
y= *(float) &i   demiş olsaydık:
i şaretçisinin gösterdiği adresteki değeri  , float olarak y değişkenine atacaktık.  burada derleyici bir tip dönüşümü işlemi uygulayacaktı. ve sonucu doğru görecektin.
fakat biz dedik ki ,  sonucu float pointer ile gönder.  Bu durumda  sayıyı bir float dönüşüm işlemine tabi tutmadı. Sadece  aldığu 4 baytlık değeri , aynen  y değişkenine aktardı.
Float sayılar  tamsayılar gibi değildir.   tamsayılarda int ve char arasındaki fark sadece  kapladıkları alan farkıdır.
Örneğin: int tipi bir değişkenin içeriği  135 ise  , bu değişkenin ilk baytının içeriği 135 ikinci baytının içeriği ise 0 dır. bu durumda  taşmamak kaydıyla  int veya char tipi değişkenlerin içeriğini birbiri arasında takas edebiliriz.
Ama float sayılarda durum farklı.   Float sayının ilk baytına 135 sayısını yazarsak , float olarak anlamsız bir sayı elde ederiz.

Bu sebeple , yukarıdaki kodda  long sayının içeriğini4 bayt olarak doğrudan  float sayının içine yazdığımız için sonuçta anlamsız bir sayı elde ettik.   bazı printf kütüphaneleri anlamsız float sayıları 0 olarak gösterir. Bu sebeple  0 olarak görmüş olabilirsiniz.
Burada *(float)&i yapasaydık doğru olurdu demiştiniz.Fakat ifadenin şu şekilde olması gerekmez mi "(float)*&i"? Zaten dediğiniz gibi yaptığımda derleyici hata veriyo.
Başlık: Ynt: C'de Temel Fonksiyonların İşleyişleri
Gönderen: Klein - 12 Mayıs 2011, 02:40:55
c esnek bir dil.  çoğu zaman  dizilim sonucun değişmesine neden olmuyorsa dizilime çok bakmaz.
örneğin  const char x ile  char const x arasında bir fark yok.
veya  aşağıdaki 3 tanım da birbirinin aynı.
void abc(char unsigned *const _far c ){
}

void abc(char unsigned  const *_far c ){
}

void abc(char unsigned  const _far *c ){
}

çoğu derleyici de buna hata vermez.

bu yüzden  bu dizilime hata verip vermeyeceğini kontrol etmedim. Hata vereceğini de düşünmemiştim açıkçası.  Sonuçta orada önemi olan  float pointere aktarma ile floata çevirip aktarma arasındaki farkı anlatmak olduğu için  çok önesemedim yıldızın nerede olduğunu.

Sonuç olarak mesele şu: 
Eğer *(tip*) &değişken  şeklinde bir dizilim olursa , bu  tip dönüşümü yapmadan verilen tipte bir pointer kullanarak içeriği verir.
eğer  (tip) *&değişken  şeklinde kullanılırsa  tip dönüşümü yaparak verir.