Russian Qt Forum

Qt => Общие вопросы => Тема начата: romanick от Апрель 24, 2013, 18:15



Название: формат числа
Отправлено: romanick от Апрель 24, 2013, 18:15
Добрый день. У меня простая и очень типичная задача, но никак  не могу найти решения...

Нужно форматировать число в строку, но так чтобы после запятой было столько знаков, сколько там реально есть.
Например
Код:
double d1 = 123123.12;
double d2 = 234234.0;

qDebug() << QString::number(d1,0,'f',2); // выводит 123123.12 - правильно
qDebug() << QString::number(d2,0,'f',2); // выводит 234234.00 - а мне нужно 234234


Название: Re: формат числа
Отправлено: m_ax от Апрель 24, 2013, 18:49
Добрый день. У меня простая и очень типичная задача, но никак  не могу найти решения...

Нужно форматировать число в строку, но так чтобы после запятой было столько знаков, сколько там реально есть.
Например
Код:
double d1 = 123123.12;
double d2 = 234234.0;

qDebug() << QString::number(d1,0,'f',2); // выводит 123123.12 - правильно
qDebug() << QString::number(d2,0,'f',2); // выводит 234234.00 - а мне нужно 234234

Если без использования Qt, то где-то я делал это так (может поможет):

Код
C++ (Qt)
template <class T>
std::string number_to_string(T x, int precission = 6) {
   std::ostringstream oss;
   oss << std::setprecision(precission) << x;
   return oss.str();
}
 


Название: Re: формат числа
Отправлено: m_ax от Апрель 24, 2013, 18:56
Вернее, я делал наоборот: из строки в число.. но не суть..


Название: Re: формат числа
Отправлено: romanick от Апрель 24, 2013, 20:05
Стандартными средствами так ничего и не придумал. Пришлось сделать это:

Код:
QString dbl2str(double value, int prec)
{
    QString s = QString::number(value, 'f', prec);
    if (s.right(3)==".00")
        s.chop(3);
    return s;
}


Название: Re: формат числа
Отправлено: Old от Апрель 24, 2013, 20:07
Стандартными средствами так ничего и не придумал. Пришлось сделать это:
А если prec будет != 2, будет работать?
А так же, если в locale установлена запятая, в качестве разделителя дробной части?


Название: Re: формат числа
Отправлено: Igors от Апрель 25, 2013, 07:02
Тогда лучше так
Код
C++ (Qt)
QString dbl2str(double value, int prec)
{
   qlonglong intVal = value;
   return (intVal == value) ? QString::number(intVal) : QString::number(value, 'f', prec);
}
Хотя обычно нули желательны, показывают что там флот


Название: Re: формат числа
Отправлено: m_ax от Апрель 25, 2013, 10:26
Тогда лучше так
Код
C++ (Qt)
QString dbl2str(double value, int prec)
{
   qlonglong intVal = value;
   return (intVal == value) ? QString::number(intVal) : QString::number(value, 'f', prec);
}
Хотя обычно нули желательны, показывают что там флот


Это не сработает, если, например, value = 0.00001, а prec < 5 


Название: Re: формат числа
Отправлено: m_ax от Апрель 25, 2013, 11:48
Вот так точно будет работать (трах-тибидох-тибидох):

Код
C++ (Qt)
template <unsigned N>
struct epsilon {
   static constexpr double value = epsilon<N-1>::value/10.0;
};
 
template <>
struct epsilon<0> {
   static constexpr double value = 1.0;
};
 
template <class T, unsigned N>
QString tostr(T x) {
   if (fabs(x) < epsilon<N>::value) return QString::number(0);
   std::ostringstream oss;
   oss << std::setprecision(N) << x;
   return QString(oss.str().c_str());
}
 


Название: Re: формат числа
Отправлено: ViTech от Апрель 25, 2013, 12:09
А если так попробовать?
Код:
qDebug() << QString::number(d1,0,'g',2);


Название: Re: формат числа
Отправлено: m_ax от Апрель 25, 2013, 12:20
А если так попробовать?
Код:
qDebug() << QString::number(d1,0,'g',2);

а второй параметр там.. это не опечатка? (не нашёл в документации)
QString::number(d1,'g',2); так да, но "Это не сработает, если, например, value = 0.00001, а prec < 5"

 


Название: Re: формат числа
Отправлено: Igors от Апрель 25, 2013, 12:44
так да, но "Это не сработает, если, например, value = 0.00001, а prec < 5"
Ну это может быть и желательно (различаем точное и округленное). А если надо - прогоним через строку
Код
C++ (Qt)
QString dbl2str(double value, int prec)
{
   QString s1 =  QString::number(value, 'f', prec);
   value = s1.toDouble();
   qlonglong intVal = value;
   return (intVal == value) ? QString::number(intVal) : s1;
}


Название: Re: формат числа
Отправлено: ViTech от Апрель 25, 2013, 15:23
а второй параметр там.. это не опечатка? (не нашёл в документации)
Если честно, то просто взял строку из первого сообщения и изменил символ, на который надо обратить внимание :). Там еще и precision для 'g' другое значение имеет: общее количество значащих цифр,  а не только после запятой. В общем, экспериментировать надо.

И переводить числа лучше с помощью QLocale, а то могут различные сюрпризы поджидать. Например, в Qt 4 QString::toDouble():
Цитировать
This function tries to interpret the string according to the current locale. The current locale is determined from the system at application startup and can be changed by calling QLocale::setDefault(). If the string cannot be interpreted according to the current locale, this function falls back on the "C" locale.
а в Qt 5 уже
Цитировать
The string conversion will always happen in the 'C' locale. For locale dependent conversion use QLocale::toDouble()
и при переходе с Qt 4 на Qt 5 можно больно по носу получить  :o. Так что это надо иметь в виду. Наверное, это и правильно, нужно с одной локалью работать, ну или по крайней мере осознанно их использовать, мало ли что там по умолчанию установлено.