2015-05-16 23 views
7

Kişisel bir proje olarak kendi tasarımımın bir CPU öykünücüsünü hedeflemek için kendi C dilim için bir derleyici yazıyorum.Diller, kaputun altında yüzen baskılarla nasıl işler?

Bunun bir parçası olarak, standart bir kayan nokta kitaplığı (tipik IEEE tek duyarlıklı) uygulamak istiyorum, ancak şamandıraları kolay okunan bir şekilde yazdırmanın bir yolunu düşünmeye çalışıyorum (Ham veri tamsayı yerine 1.2345, düşünebildiğim en iyisi, 2 için değerler üretiyor ve baskı için uygun bir biçimde numarayı almak için bazı garip çarpmalar yapıyor.

Bir kayan yazıyı kolayca yazdırılabilir bir formata dönüştürmek için veya printf("%f",float_value); kullanmadan uygulanabilen bir şamandıranın yazdırılması veya C benzeri bir dilde dökümler için bir algoritma var mı?

+1

Tabii, bir uygulama bakmak niye printf'ın –

+0

Ya da bunlardan biri, örneğin, kaynak kodu indirme için mevcut olduğu için 'glibc'. –

+0

[c/C++ işlevlerinin kaynak kodu] 'nın olası bir kopyası (http://stackoverflow.com/questions/1127328/source-code-of-cc-functions) –

cevap

3

Bir işlevin kirli bir şekilde kesilmesi olabilir, ancak bunu, kayan nokta sayılarını düzgün şekilde görüntülemek için bir işlev için temel olarak kullanabilirsiniz. Putchar'dan başka bir şey yazdırmak için başka bir yardımcı işlev kullanmaz ve tüm durumları kapsamaz (numaranız bir NaN, hatta negatiftir!), Fakat, sadece bir başlangıç ​​noktasıdır. :

#include <stdio.h> 

void printfloat (float n) 
{ 
    int whole = n; 
    int power = 1; 
    int digit; 

    /* Find out the largest divisor for printing the integer part */ 
    while (whole>=1) 
    { 
     whole /= 10; 
     power *= 10; 
    } 
    power /= 10; 

    /* Prints the integer part of the number */ 
    whole = n; 
    while (power>=1) 
    { 
     digit = whole/power; 
     whole %= power; 
     putchar ('0'+digit); 
     power /= 10; 
    } 

    /* Prints the decimal point */ 
    putchar ('.'); 

    /* And now the fractional part */ 
    n = n-(int)n; 
    while(n!=0) 
    { 
     digit = n*10; 
     putchar ('0'+digit); 
     n*=10; 
     n = n-(int)n; 
    } 
    putchar ('\n'); 
} 

int main() 
{ 
    float n = 123.45678; 

    printfloat(n); 
    return 0; 
} 

burada test edebilirsiniz: anlıyorum gibi http://goo.gl/V4pgNZ

+3

Hayır, bu uygun bir işlevin temeli olarak kullanılamaz. Bu sadece kirli bir hack, ve doğru bir şekilde çalışan bir şeye geçmek için bir tane atmak gerekiyor. Savunduğunuzda, sıfırdan C'ye doğru bir ikili-ondalık kesimi uygulamak temel olarak, en azından ilkel bignum kütüphanesini uygulayarak başlamalıdır (http://www.openwall.com/lists/musl/2012/04/10/6) ancak doğru sürümü yapmak istemiyorsa, en azından http://www.opensource.apple.com/source/ruby/ruby-18/ruby/missing/strtod.c?txt adresinde yapılabilir. Ve http://www.exploringbinary.com/ couse okuyun. –

6

, kayan nokta sayıları yazdırmak için tekniğin bilinen durumu Florian Loitsch tarafından algoritmaların Grisu ailedir. here numaralı kağıdı okuyabilirsiniz. (Ve tersi), iyice Rick Regan siteyi tavsiye onluya ikili kayan nokta dönüştürme konulara biraz daha kolay giriş için

, http://www.exploringbinary.com/