2009-12-29 113 views
7

我有一個字符串,它看起來像這樣:格式字符串轉換成科學記數法

"0.4794255386042030002732879352156" 

這大約是罪(0.5)。我想格式化字符串,以看起來更漂亮

"4.794255386042e-1" 

我怎樣才能做到這一點?記住我正在處理字符串而不是數字(float,double)。此外,我需要輪流保持數字儘可能準確,我不能只是截斷。如果我需要轉換成不同的數據類型,我寧願長雙,因爲常規的雙不具有足夠的精度。在舍入之前我至少需要12位十進制數字。也許我可以做一個簡單的sprintf()轉換。

回答

8

像這樣:

#include<iostream> 
using namespace std; 

int main() 
{ 
     char *s = "0.4794255386042030002732879352156"; 
     double d; 

     sscanf(s,"%lf",&d); 
     printf("%.12e\n",d); 

     return EXIT_SUCCESS; 
} 

輸出:

# g++ a.cpp && ./a.out 
4.794255386042e-01 
0

有一個在C或C中沒有標準功能++做到這一點。正常的做法是要麼轉換爲數字(然後使用標準功能格式化號碼)或寫自己的自定義輸出功能。

2

在高度便攜C下面輸出工作實例:

result is 4.794255386042E-01 


#include <stdio.h> 

int main() 
{ 
    char *str = "0.4794255386042030002732879352156"; 

    double f; 
    char newstr [50]; 
    // convert string in `str` to float 
    sscanf (str, "%le", &f); 

    sprintf (newstr, "%.12E", f); 
    printf ("result is %s\n", newstr); 
    return 0; 
} 
0
#include <iostream> 
using namespace std; 
... 
double dd = strtod(str); 
cout << scientific << dd << endl; 
+0

沒有,輸出0.4794255386042030002732879352156,這是不是他提出的要求。 – dcp 2009-12-29 19:40:24

+0

不,它輸出4.794255e-01(默認精度爲6)。 'cout.precision(12)'將它設置爲十二。 – 2009-12-30 17:42:49

1

轉換爲長雙使用sscanf(),然後用sprintf()打印它背出來作爲一個字符串,用科學的格式:

long double x; 
char num[64]; 

if(sscanf(string, "%Lf", &x) == 1) 
    sprintf(num, "%.12Le", x); 

不知道如果連long double實際上給你12個顯著數字,雖然。在我的系統,這會產生"4.79425538604e-01"

+0

你的意思是if(sscanf(string,「%Lf」,&x)== 1),因爲%Ld給出一個長整數? – 2009-12-30 02:36:00

+0

@John:是的,謝謝! – unwind 2009-12-30 17:22:02

0

根據你想要多少個小數位(12在這種情況下),你可以做這樣的事情:

int main() { 
    char buff[500]; 
    string x = "0.4794255386042030002732879352156"; 
    double f = atof(x.c_str()); 
    sprintf(buff,"%.12fe-1",f*10); 
    cout<<buff<<endl; 
    return 0; 
} 

結果: ----------捕獲輸出--- -------

「C:\ Windows \ System32下\ cmd.exe的」 /cc:\temp\temp.exe 4.794255386042e-1 ,退出代碼終止0

2

看在你的問題中的字符串,它似乎你正在使用基數爲10的對數。在這種情況下,它不會是比較容易僅計算的開頭或結尾零,並提出,在指數,通過直接掃描字符串?

也許我失去了一些東西..

+0

同意。在這種情況下,他可以簡單地找到該點的位置,移動該點,並將指數附加爲該點移動的距離和方向的數量。 – Clifford 2009-12-29 19:46:04

1

一個IEEE 754 64位浮點(即雙精度),是良好的15位數字顯著,所以你應該沒有問題轉化爲一倍。您更可能遇到讓格式說明符顯示所有可用數字的問題。雖然從發佈的例子來看,這似乎並非如此。

+0

你是正確的,一旦我加入了正確的格式字符串,就足夠好了我甚至從一個雙精度型中得到了17位十進制數,我相信我可以得到更多,但這是很多。 – 2009-12-30 03:44:40

+0

沒有雙重的你不能!事實上,不管你得到什麼,甚至不可能有17個。尾數是52位,2^52是16位十進制數,所以限制是15位(數學上爲15.65位),因爲52位足以代表所有可能的15位數。請注意,我在談論*有效數字*而非小數位。 – Clifford 2009-12-30 08:27:14

6

你在尋找類似於this的產品嗎?

這裏有一個例子:

// modify basefield 
#include <iostream> 
#include <sstream> 

using namespace std; 

int main() { 
    std::string numbers("0.4794255386042030002732879352156"); 
    std::stringstream stream; 
    stream << numbers; 
    double number_fmt; 
    stream >> number_fmt; 
    cout.precision(30); 

    cout << number_fmt << endl; 

    cout.precision(5); 
    cout << scientific << number_fmt << endl; 
    return 0; 
} 

輸出:

0.479425538604203005377257795772

4.79426e-01

相關問題