2009-09-30 4 views
1

Я хочу преобразовать double в строку с фиксированной шириной.Преобразование double в String с фиксированной шириной

Если ширина равна 10, то я хочу, чтобы двойное значение округлялось до этой ширины.

Например, если значение = 102,121323435345 и шириной 10, то это значение должно быть,

 
position==> 
      value = 102.121323 

я могу добиться этого с snprintf, но я ищу для C++ родной код, чтобы сделать то же самое.


char buf[125]; 
snprint(buf, width, "%.6f", value); 

Я пытался использовать ниже, но это не помогает мне много,


std::ostringstream oss; 
oss << std::fixed << std::setw(10) << std::precision(6) << value; 

станд :: setw guarantiees минимальную ширину для значения и, если значение больше, чем размер по ширине , он не округляет значения.

Спасибо.

+0

Что-то, что мне не совсем понятно: пытаетесь ли вы печатать с шириной 10, как в вашем примере вывода, или 4 десятичных знака, например, в вашем c-коде? – Martin

+0

Почему вы против использования snprintf? Это вполне допустимый C++. Для этого остринский поток слишком завален. – Vitali

+0

@Martin, я хочу, чтобы ширина всегда была постоянной –

ответ

1

Это то, что вы хотите? Здесь мы вычисляем количество доступной точности и соответственно устанавливаем ostream.

#include <iostream> 
    #include <iomanip> 

    using namespace std; 

    int main(int argc, char* argv[]) 
    { 
    // Input 
    double value = 102.1213239999; 
    // Calculate limits 
    int digits = ((value<1) ? 1 : int(1+log10(double(abs(value))))); 
    int width = 10; 
    int precision = (((width-digits-1)>=0) ? (width-digits-1):0); 

    // Display 
    cout.setf(ios::fixed); 
    cout.precision(precision); 
    cout<<setw(10)<<value<<endl; 


    return 0; 

    } 
    OUTPUT: 102.121324 

Btw, если вы хотите грузовик способов для вычисления цифр, here's how.

+0

OP требует максимальной производительности 10 символов с максимальной точностью. – mob

+0

Что происходит, когда значение> 1е9? – Jacob

+0

Как нас найти? Он не останется на 10 символов, если он больше 1e9, но проблема точности решена (я думаю). – Jacob

2

Как о лексическом гипсе?

double x = 102.1213239999; 
std::cout << boost::lexical_cast<std::string>(x).substr(0,10); 

Его не совсем то, что вы просили. Я просто пытался мыслить вне коробки.
Вы также можете захотеть взглянуть на этот вопрос для обсуждения по форматированию differences between C and C++ и проверить Boost Format Library

+1

Это неправильно. Рассмотрим этот номер: double x = 12345678901. Ваш ответ будет отключен по порядку. – Vitali

+0

Несмотря на то, что пример неверен, предложение посмотреть библиотеку Boost Format стоит +1. – MP24

+0

@unknown: Я считаю, что абсолютные утверждения обычно неправильны (это, вероятно, не очень хорошее решение).Я знаю, что большие значения будут усечены, но вопрос заключается в том, что данные в фиксированном размере не соответствуют точности (в противном случае решение тривиально использует ширину манипулятора (10)). В исходном вопросе snprint() используется для усечения вывода, эта альтернатива предоставляет эквивалентное (но аккуратное) решение в C++. Реальный вопрос заключается в том, что вы делаете, когда у вас есть поле вывода фиксированного размера, а значение больше! Вот почему width (x) определяет минимальную ширину, а не максимальную ширину. –

2

Вы можете использовать osteram::width и ostream::precision функции для достижения этой цели, как этого

std::ostringstream out; 
out.width(10); 
out.precision(10); 
out << 123.12345678910111213; 

Хотя он выиграл 't добавить нули после точки, чтобы уважать ширину, но она добавит пробелы (или любой символ, который вы выбираете) перед номером. Таким образом, вы получите «102» или «0000000102» (если вы вызываете out.fill ('0');) вместо «102.000000», если вы передаете 102 в качестве входного значения.

Смежные вопросы