У меня есть строка, которая похожа на это:
"0.4794255386042030002732879352156"
который является приблизительно sin(0.5). Я хотел бы отформатировать строку для взгляда намного более хорошего
"4.794255386042e-1"
Как я могу достигнуть этого? Помните, что я имею дело со строками и не числами (плавание, дважды). Также я должен к раунду сохранить число максимально точным, я не могу просто усечь. Если бы я должен преобразовать в другой тип данных, я предпочел бы длинное двойное, потому что у двойного постоянного клиента нет достаточной точности. Я хотел бы по крайней мере 12 десятичных цифр перед округлением. Возможно, существует простой sprintf () преобразование, которое я мог сделать.
Вывод:
#include<iostream>
using namespace std;
int main()
{
char *s = "0.4794255386042030002732879352156";
double d;
sscanf(s,"%lf",&d);
printf("%.12e\n",d);
return EXIT_SUCCESS;
}
Вы ищете что-то вроде этого?
Вот пример:
// 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.47942553860420300537725779572
4.79426e-01
В очень портативном 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;
}
IEEE 754 64-битный float (т.е. двойная точность), хорош для 15 десятичных значащих цифр, так что у вас не должно возникнуть проблем с преобразованием в double. Скорее всего, вы столкнетесь с проблемой получения спецификатора формата для отображения всех доступных цифр. Хотя из приведенных примеров кажется, что это не так
.Convert to long double используя sscanf()
, а затем с помощью sprintf()
распечатать его обратно в виде строки, используя научный формат:
long double x;
char num[64];
if(sscanf(string, "%Lf", &x) == 1)
sprintf(num, "%.12Le", x);
Не уверен, что даже long double
на самом деле дает 12 значащих цифр. В моей системе это генерирует "4.79425538604e-01"
.
Глядя на строки в вашем вопросе, кажется, что вы используете логарифмы base-10. В таком случае, не будет ли относительно легко просто посчитать ведущие или трейлинговые нули и поместить их в экспоненту, непосредственно сканируя строки?
Может быть, я что-то пропустил...
.Для этого ни в C, ни в C++ нет стандартной функции. Обычный подход заключается либо в преобразовании в число (а затем использовании стандартных функций для форматирования числа), либо в написании собственной пользовательской выходной функции.
.#include <iostream>
using namespace std;
...
double dd = strtod( str );
cout << scientific << dd << endl;
В зависимости от желаемого количества десятичных разрядов (в данном случае 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" /c c:\temp\temp.exe 4.794255386042e-1 Прекращено кодом выхода 0.