Russian Qt Forum

Qt => Общие вопросы => Тема начата: PavelVX от Август 28, 2012, 08:36



Название: Преобразование значений
Отправлено: PavelVX от Август 28, 2012, 08:36
Доброго времени суток!
Понадобилось написать универсальную функцию получающую значения из БД. Написал, но наткнулся на необъяснимое для меня поведение.
    QVariant tst = 32192.96;
    double itog = tst.toDouble();
    qDebug() << itog;
Выведет 32193!!!! но почему????
tst.toString() выведет все как надо.
Начал копать дальше. Получил странный результат: tst.toDouble() почему-то выводит только 5 первых символов.
 tst = 1221937.41; -> 1.22194e+06
Не могли бы более опытные товарищи объяснить, где я не прав или кинуть ссылку на понимание данного поведения.
Всего-то хотелось получать значения из БД, а потом уже приводить к нужному типу, в зависимости от задачи.


Название: Re: Преобразование значений QVariant->double. результат непредсказуем.
Отправлено: LisandreL от Август 28, 2012, 09:06
Выведет 32193!!!! но почему????
Потому, что QDebug считает такую точность вывода достаточной. То есть преобразуется всё правильно, просто так выводится:
Код
C++ (Qt)
QVariant tst = 32192.96;
double itog = tst.toDouble();
qDebug() << QString::number( itog, 'G', 10 );
"32192.96"

Ну и да, числа с плавающей точкой хранятся не совсем точно, так что без задания количества значащих разрядов никуда:
Код
C++ (Qt)
QVariant tst = 32192.96;
double itog = tst.toDouble();
qDebug() << QString::number( itog, 'G', 100 );
"32192.9599999999991268850862979888916015625"


Название: Re: Преобразование значений QVariant->double. результат непредсказуем.
Отправлено: PavelVX от Август 28, 2012, 10:40
Хмм, просто меня засмущало то, что не один qDebug() считает округление нормальным:
QVariant tst = 32192.96;
double itog = tst.toDouble();
QLineEdit->setText(itog);
выведет 32193.


Название: Re: Преобразование значений QVariant->double. результат непредсказуем.
Отправлено: LisandreL от Август 28, 2012, 11:17
Видимо 6 знаков - у них стандарт (в первом случае просто в округлённом 32193.0 ноль опущен).
Цитировать
QLineEdit->setText(itog);
Нет у QLineEdit такого сетера.


Название: Re: Преобразование значений QVariant->double. результат непредсказуем.
Отправлено: PavelVX от Август 28, 2012, 11:55
QLineEdit->setText(QString("%1").arg(itog));


Название: Re: Преобразование значений QVariant->double. результат непредсказуем.
Отправлено: kambala от Август 28, 2012, 12:08
лучше уж QString::number()


Название: Re: Преобразование значений QVariant->double
Отправлено: PavelVX от Сентябрь 12, 2012, 08:00
А подскажите пожалуйста такую вещь: как мне получить дробную часть без изменений?
double dtmp = 234.24;
int n1, n2;
Хочу в n1 получить целую часть, в n2 дробную.
n1 = dtmp; // все отлично.
n2 = (dtmp - n1)*100; //тут начинаются проблемы: n2 - 23, из-за того, что при преобразовании dtmp = 234.239999;
Как быть-то?


Название: Re: Преобразование значений QVariant->double
Отправлено: V1KT0P от Сентябрь 12, 2012, 08:24
А подскажите пожалуйста такую вещь: как мне получить дробную часть без изменений?
double dtmp = 234.24;
int n1, n2;
Хочу в n1 получить целую часть, в n2 дробную.
n1 = dtmp; // все отлично.
n2 = (dtmp - n1)*100; //тут начинаются проблемы: n2 - 23, из-за того, что при преобразовании dtmp = 234.239999;
Как быть-то?
О боже, чем тебя не угодила стандартная функция modf для таких вещей: http://www.cplusplus.com/reference/clibrary/cmath/modf/ (http://www.cplusplus.com/reference/clibrary/cmath/modf/)


Название: Re: Преобразование значений
Отправлено: PavelVX от Сентябрь 12, 2012, 08:26
Видимо тем же:
    dtmp = modf(dtmp, &tmp);
    n2 = dtmp*100; //23!


Название: Re: Преобразование значений
Отправлено: V1KT0P от Сентябрь 12, 2012, 08:55
Видимо тем же:
    dtmp = modf(dtmp, &tmp);
    n2 = dtmp*100; //23!

Код
C++ (Qt)
   double param, fractpart, intpart;
   param = 234.24;
   fractpart = modf (param , &intpart);
   int value = static_cast<int>(intpart);
В итоге: fractpart = 0.2400000, intpart = 234.000000, value = 234.