Russian Qt Forum
Ноябрь 24, 2024, 11:51 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: формат числа  (Прочитано 6126 раз)
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
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #1 : Апрель 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();
}
 
« Последнее редактирование: Апрель 24, 2013, 18:53 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #2 : Апрель 24, 2013, 18:56 »

Вернее, я делал наоборот: из строки в число.. но не суть..
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
romanick
Гость
« Ответ #3 : Апрель 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;
}
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Апрель 24, 2013, 20:07 »

Стандартными средствами так ничего и не придумал. Пришлось сделать это:
А если prec будет != 2, будет работать?
А так же, если в locale установлена запятая, в качестве разделителя дробной части?
« Последнее редактирование: Апрель 24, 2013, 22:44 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Апрель 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);
}
Хотя обычно нули желательны, показывают что там флот
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #6 : Апрель 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 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #7 : Апрель 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());
}
 
« Последнее редактирование: Апрель 25, 2013, 12:00 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #8 : Апрель 25, 2013, 12:09 »

А если так попробовать?
Код:
qDebug() << QString::number(d1,0,'g',2);
Записан

Пока сам не сделаешь...
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #9 : Апрель 25, 2013, 12:20 »

А если так попробовать?
Код:
qDebug() << QString::number(d1,0,'g',2);

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

 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Апрель 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;
}
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #11 : Апрель 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 можно больно по носу получить  Шокированный. Так что это надо иметь в виду. Наверное, это и правильно, нужно с одной локалью работать, ну или по крайней мере осознанно их использовать, мало ли что там по умолчанию установлено.
Записан

Пока сам не сделаешь...
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.25 секунд. Запросов: 22.