2010-12-05 93 views
3

我正在研究一個嵌入式應用程序,需要打印浮點值。由於空間和其他限制,我只能使用putchar()輸出。如何使用putchar打印浮點值?

我想創建一個函數,它將float作爲參數並使用putchar()打印出來。我有一個類似的函數可用於整數值。

void putLong(long x) 
{ 
    if(x < 0) 
    { 
     putchar('-'); 
     x = -x; 
    } 
    if (x >= 10) 
    { 
     putLong(x/10); 
    } 
    putchar(x % 10+'0'); 
} 

我怎麼能做一個類似的浮動功能?

+2

你碰巧知道浮動是否遵循嵌入式系統上的IEEE 754標準,或者它們是否以其他方式表示? – 2010-12-05 03:44:06

回答

0

我認爲我的主要做法是將浮點數的整數部分與小數部分分開。

如果您可以使用某種舍入或轉換爲整數函數,則可以使用putLong方法輸出整數部分。

輸出一個小數點。

然後,從浮點數中減去該int以隔離小數。現在,對於小數點,您可以嘗試確定小數點後面的位數,或者僅乘以10的任意大的冪,然後從結果int的右側去除多餘的零,並再次應用putLong爲結果。

我懷疑可能有更高效或更簡單的方法來做到這一點,但我很肯定這種方法可行。查找浮點數用於表示指數和值的組件也可能有用。

+0

這個「工作」的程度很大程度上取決於您的要求。對於大於整數類型可以存儲的最大值的值,它根本無法工作。 – 2010-12-05 03:40:38

+0

@R:這是真的,但是,你會說,分離值的前後小數部分的基本概念是有效的,即使你必須做一些額外的內存操作或使用大型數據類型? – DGH 2010-12-05 03:44:25

1

你需要什麼樣的數值範圍和精度/精度要求?以十進制打印浮點數的確切值是一個非常困難的問題,如果你需要高達8 kb左右的工作空間(我可能會失去2個冪的權力;這是我的頭頂)支持80位或128位long double值。如果你只支持double,你可能會得到1 kb左右,如果你只是想打印不好的近似值,基本上沒有工作空間。

OK,所以這裏是一個非常基本的版本:

void putDouble(double x, int p) 
{ 
    long d; 
    if (x<0) { 
     putchar('-'); 
     x=-x; 
    } 
    d = x; 
    putLong(d); 
    putchar('.'); 
    while (p--) { 
     x = (x - d) * 10; 
     d = x; 
     putchar('0'+d); 
    } 
} 

你可能想解決您putLong處理比2位長的數字,2 :-)

2

這裏是一個可能的解決方案:

typedef enum 
{ 
    DEC1 = 10, 
    DEC2 = 100, 
    DEC3 = 1000, 
    DEC4 = 10000, 
    DEC5 = 100000, 
    DEC6 = 1000000, 

} tPrecision ; 

void putFloat(float f, tPrecision p) 
{ 
    long i = (long)f ; 
    putLong(i) ; 
    f = (f - i) * p ; 
    i = abs((long)f) ; 
    if(fabs(f) - i >= 0.5f) 
    { 
     i++ ; 
    } 
    putchar('.') ; 
    putLong(i) ; 
    putchar('\n') ; 
} 

你會這樣使用它:

putFloat(3.14159f, DEC3) ; 

將輸出「3.142」,注意第三位數字的湊整。

如果您只需要固定的小數位數,您可以取消精度參數並對其進行硬編碼。

使用此功能時,你應該知道的浮標只有6 顯著位精度,不是6個小數。所以如果你試圖用DEC6打印123.456,你會在第三名後得到錯誤的數字。應忽略第6位有效數字後的任何數字,但編寫代碼時考慮到這一點,在您的應用程序中可能是不必要的,或者您希望給出的約束條件更貴。