2009-12-29 39 views
7

Tôi có một chuỗi mà trông như thế này:Format chuỗi thành ký hiệu khoa học

"0.4794255386042030002732879352156" 

đó là xấp xỉ sin (0.5). Tôi muốn định dạng chuỗi để trông đẹp hơn nhiều

"4.794255386042e-1" 

Làm cách nào để đạt được điều này? Hãy nhớ rằng tôi đang xử lý các chuỗi và không phải là số (float, double). Ngoài ra tôi cần phải làm tròn để giữ số càng chính xác càng tốt, tôi không thể cắt ngắn. Nếu tôi cần phải chuyển đổi sang một kiểu dữ liệu khác, tôi muốn có một double dài hơn vì một double thường xuyên không có đủ độ chính xác. Tôi muốn có ít nhất 12 chữ số thập phân trước khi làm tròn. Có lẽ có một chuyển đổi sprintf() đơn giản mà tôi có thể làm.

Trả lời

8

Something như thế này:

#include<iostream> 
using namespace std; 

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

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

     return EXIT_SUCCESS; 
} 

Output:

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

Không có hàm chuẩn trong C hoặc C++ để thực hiện việc này. Cách tiếp cận thông thường là chuyển đổi sang một số (và sau đó sử dụng các hàm chuẩn để định dạng số) hoặc viết hàm đầu ra tùy chỉnh của riêng bạn.

2

Trong cao xách tay C ví dụ làm việc bên dưới kết quả đầu ra:

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

Không, đó là kết quả đầu ra 0,4794255386042030002732879352156, mà không phải là những gì ông yêu cầu. – dcp

+0

Không, nó xuất ra 4.794255e-01 (độ chính xác mặc định là 6). 'cout.precision (12)' sẽ đặt thành mười hai. –

1

Convert to long double sử dụng.210, sau đó sử dụng sprintf() in nó lại ra như là một chuỗi, bằng cách sử dụng định dạng khoa học:

long double x; 
char num[64]; 

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

Không chắc nếu ngay cả long double thực sự mang đến cho bạn 12 chữ số có nghĩa, mặc dù. Trên hệ thống của tôi, điều này tạo ra "4.79425538604e-01".

+0

bạn có nghĩa là nếu (sscanf (string, "% Lf", & x) == 1) vì% Ld cho một số nguyên dài? –

+0

@ John: Vâng, cảm ơn! – unwind

0

Tùy thuộc vào có bao nhiêu chữ số thập phân mà bạn muốn (12 trong trường hợp này), bạn có thể làm một cái gì đó như thế này:

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; 
} 

Kết quả: ---------- Capture Output --- -------

"c: \ windows \ system32 \ cmd.exe" /cc:\temp\temp.exe 4.794255386042e-1 Kết thúc với mã thoát 0.

2

Nhìn vào các chuỗi trong câu hỏi của bạn, có vẻ như bạn đang sử dụng logarit cơ sở-10. Trong trường hợp đó, nó sẽ không tương đối dễ dàng để chỉ đếm số 0 đầu hoặc cuối và đặt nó vào một số mũ, bằng cách quét các chuỗi trực tiếp?

Có lẽ tôi đang thiếu một cái gì đó ..

+0

Đồng ý. Trong trường hợp này, anh ta chỉ đơn giản có thể tìm thấy vị trí của điểm, di chuyển nó và nối thêm số mũ như là một số cách xa và theo hướng mà điểm được di chuyển. – Clifford

1

Một IEEE 754 64 bit float (chính xác ví dụ kép), là tốt cho 15 con số đáng kể chữ số thập phân, vì vậy bạn nên không có vấn đề chuyển đổi để tăng gấp đôi. Bạn có nhiều khả năng gặp sự cố khi nhận định dạng thông số để hiển thị tất cả các chữ số có sẵn. Mặc dù từ các ví dụ được đăng, điều này có vẻ không đúng.

+0

bạn đúng là một đôi là đủ tốt một khi tôi được thêm vào trong một chuỗi định dạng thích hợp tôi thậm chí có 17 chữ số thập phân trong một đôi, tôi chắc chắn tôi có thể nhận được nhiều hơn nhưng đó là rất nhiều. –

+0

Không phải với một đôi bạn không thể! Trong thực tế, ngay cả 17 là có thể bất kể những gì bạn điều bạn có. Phần định trị là 52 bit, 2^52 là số thập phân 16 chữ số, vì vậy giới hạn là 15 chữ số (bằng 15,65 chữ số toán học) vì 52 bit đủ để biểu diễn tất cả các số có thể có 15 chữ số. Lưu ý rằng tôi đang nói về * số liệu quan trọng * không phải là số thập phân. – Clifford

6

Bạn đang tìm kiếm thứ gì đó như this?

Đây là một mẫu:

// 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; 
} 

Output:

0,479425538604203005377257795772

4.79426e-01

Các vấn đề liên quan