2013-07-27 72 views
0
  • 平臺:Linux 3.2.0(Debian的7.0)
  • 編譯器:GCC 4.7.2(Debian的4.7.2-5)

我想字符串轉換成浮動。我知道已經有這樣做的功能。我只是在做這個練習。我的函數適用於123.123,1234,-678.8等簡單數字。但是當我嘗試將字符串.99999999轉換爲浮點數時,我最終得到1.這顯然是一個問題。我不知道這是否是因爲.99999999不能用浮動表示,或者如果我錯誤地做了某些事情。我所問的問題是如何計算浮動可以表達的最大分數。由於缺乏更好的術語,我怎麼知道浮球何時會溢出?最大浮動分數

這是我到目前爲止。

#include <stdio.h> 
#include <stdlib.h> 
#include <float.h> 

int cstrtof(const char *cstr, float *f); 
int cstrtof(const char *cstr, float *f) 
{ 
unsigned short int i = 0; 
unsigned short int bool_fraction = 0; 
float tmp_f = 0; 

if(cstr[0] == '\000') return -1; 
else if(cstr[0] == '-') i = 1; 

for(; cstr[i] != '\000'; i++) 
{ 
    printf("tmp_f = %f\n", tmp_f); 
    if(cstr[i] >= '0' && cstr[i] <= '9') 
    { 
     if(tmp_f > (FLT_MAX - (cstr[i] - '0'))/10) return -2; 
     else tmp_f = tmp_f * 10 + (cstr[i] - '0'); 
    } 
    else if(cstr[i] == '.') bool_fraction = i+1; 
    else return i+1; 
} 

printf("tmp_f = %f\nbool_fraction = %i\n", tmp_f, bool_fraction); 

if(bool_fraction) 
{ 
    for(bool_fraction--; bool_fraction < i-1; bool_fraction++, tmp_f /= 10) 
    { 
     printf("tmp_f = %f\n", tmp_f); 
    } 
} 

printf("tmp_f = %f\nbool_fraction = %i\n", tmp_f, bool_fraction); 

if(cstr[0] == '-') *f = tmp_f*-1; 
else *f = tmp_f; 

return 0; 
} 

int main(int argc, char *argv[]) 
{ 
float f = 0; 
int return_value = 0; 

return_value = cstrtof(argv[1], &f); 
if(return_value == 0) 
{ 
    printf("f = %.11f\n", f); 
} 
else if(return_value == -1) 
{ 
    printf("ERROR Empty String\n"); 
} 
else if(return_value == -2) 
{ 
    printf("ERROR Data Type Overflow\n"); 
} 
else 
{ 
    printf("ERROR Invalid character '%c'\n", argv[1][return_value-1]); 
} 

return 0; 
} 

另外cstrtof()基於以下函數。

int cstrtoslli(const char *cstr, signed long long int *slli) 
{ 
unsigned short int i = 0; 
signed long long int tmp_slli = 0; 

if(cstr[0] == '\000') return -1; 
else if(cstr[0] == '-') i = 1; 
else if(cstr[0] == '0') return -2; 

for(; cstr[i] != '\000'; i++) 
{ 
    if(cstr[i] >= '0' && cstr[i] <= '9') 
    { 
       //LLONG_MAX is defined in limits.h 
     if(tmp_slli > (LLONG_MAX - (cstr[i] - '0'))/10) return -3; 
     else tmp_slli = tmp_slli * 10 + (cstr[i] - '0'); 
    } 
    else return i+1; 
} 

if(cstr[0] == '-') *slli = tmp_slli*-1; 
else *slli = tmp_slli; 

return 0; 
} 
+0

「我知道已經有這樣做的功能」 - >你有沒有考慮過使用這些函數作爲參考?編寫'strtof(「。99999999」,...)'比在StackOverflow上提出問題要快。 –

回答

2

可表示的最大float小於1值由nexttowardf(1, -INFINITY)返回。

這通常會有一個不同的小數部分,例如,小於2的最大可表示的float值,即nexttowardf(2, -INFINITY)。這是因爲不同大小的數字通常具有不同數量的可用於小數部分的比特數(因爲一些比特用於整數部分)。大數部分有零位。

float是IEEE-754 32位二進制浮點值,這在現代實現中很常見,低於1的最大的float是0.999999940395355224609375。當將十進制數字轉換爲float的例程質量良好且舍入模式爲最近(通用默認值)時,數字從舍入切換到0.999999940395355224609375以四捨五入爲1的點位於這兩個值之間(以及確切的中點將舍入到1)。

正確地將十進制數字轉換爲二進制浮點很複雜。這是一個解決的問題,並且有關於它的學術論文,但是如果它正在正確地完成這項工作,你通常應該依賴現有的圖書館代碼。自己做正確的做法需要大量的時間投入。

1

我在問的問題是如何計算float可以表示的最大分數。由於缺乏更好的術語,我怎麼知道浮球何時會溢出?

您正在尋找:

#include <math.h> 
… nextafterf(1.0f, 0.0f) … 

但是,你應該與C99的十六進制表示熟悉的花車,然後你就可以不斷的直接寫:0x1.fffffep-1

+0

或'0x.ffffffp0' –