Как конвертировать float/double в строку именно в том виде, в котором значение устновленно в переменной (без обрезки занков)?
К своему удивлению не нашёл функции записи float/double в строку в исходном виде переменной:
float val = 0.012345678900000;
std::string strval;
snprintf(&strval[0], strval.capacity(), "%g", val);
printf("%s\n", strval.data());
Выводит "0.01234567", а надо "0.012345678900000". stringstream пробовал - результат тот же. std::to_string вообще 6 знаков пишет после точки.
Точность заранее не известна, нужно выгружать в строку то, что есть, можно без нулей в конце.
Как это сделать?
Ответы (1 шт):
float valf = 0.012345678900100;
double vald = 0.012345678900100;
printf("%.20f\n", valf);
printf("%.20lf\n", vald);
Вывод:
0.01234567910432815552
0.01234567890010000030
В любом случае в силу того, что числа с плавающей точкой представлены в итоге виде суммы степеней двойки, ожидать, что введенный строковый литерал или результат вычисления будет равен чему-то конкретному, не приходится.
Пробуйте
char buf[30];
sprintf(buf,"%.20lf",val);
string s = buf;
Или
ostringstream os;
os << setprecision(20) << vald;
string s = os.str();
cout << s << endl;
Только не пишите в никуда, как в вашем примере...
Update
К "артефактам", упомянутым в комментарии. Это не артефакты. Представим, что у нас есть возможность записи только 4 бит. Как вы представите, например, 1/5 в виде суммы дробей вида 1/2n?
1/8 + 1/16 + 1/128... Стоп! Уже не можем представить 1/128 - точности не хватает. Так что число 0.20 будет иметь вид 0.1875.
Это - ограничение самого представления. Ну невозможно в общем случае представить дробное число с помощью конечной суммы дробей вида 1/2n...