Конвертировать double в строку с фиксированной записью, без конечных нулей и без sprintf

Этот вопрос задавался пару раз, но все ответы либо относятся к sprintf, либо включают удаление конечных нулей вручную. Неужели нет лучшего способа? разве невозможно достичь этого с std::stringstream?

1

Решение

Сначала вы вычисляете, сколько потенциальных цифр у вас есть до и после десятичной дроби:

int digits_before = 1 + (int)floor(log10(fabs(value)));
int digits_after = std::numeric_limits<double>::digits10 - digits_before;

Затем вы узнаете, сколько из этих цифр являются нулями:

double whole = floor(pow(10, digits_after) * fabs(value) + 0.5);
while (digits_after > 0 && (whole/10.0 - floor(whole/10.0)) < 0.05)
{
--digits_after;
whole = floor(whole / 10.0 + 0.5);
}
if (digits_after < 0) digits_after = 0;

Теперь у вас есть значение, которое вы можете использовать с std::setprecision:

std::stringstream ss;
ss << std::fixed << std::setprecision(digits_after) << value;

В конечном итоге это большая работа и дублирование усилий, которые в любом случае выполняет преобразование строк, поэтому люди обычно просто преобразовывают в строку и удаляют завершающие нули. И нет, для этого нет простого способа форматирования, вам придется делать это трудным путем или не делать это вообще.

Смотрите приведенный выше код в действии: http://ideone.com/HAk55Y

4

Другие решения

Если цель состоит в том, чтобы иметь фиксированную точку x или меньше для конечных нулей, подбросьте двойную через фиксированный поток. Затем отрежьте оставшиеся с нефиксированным выходом.

double number = 1.03000;
std::stringstream s.precision(6);

s << number;
std::cout << s.str();

Редактировать:
Сохранить результаты

std::string result = s.str();
-1

По вопросам рекламы [email protected]