Qt/C++ - Lesson 057. Mistakes of output qDebug() for floating-point numbers

Qt, qDebug, float

When developing software to Qt had a chance encounter with one nuance when outputting floating point numbers through qDebug() . The problem is that not all characters are displayed after the decimal point. In the same sins and output std::cout .

This user case may occur in the following situation:

You have a QString object that contains a certain number of "8564.26495574", which we translate into a floating point number using toDouble() method, and check the result with the output qDebug (), but that's bad luck, the output is false.

QString str("8564.26495574");
qDebug() << str.toDouble();

// The output is -> 8564.26

But in fact we have absolutely the right number, that is, from a string was received number 8564.26495574 just concluded qDebug() shows the rounded result.

The same can be observed if you try to bring a double number value to qDebug() .

double a = 8564.26495574;
qDebug() << a;

// The output is -> 8564.26

Make sure that no errors occur when converting numbers from QString to a double can, using the bool variable, a pointer to which is passed as an argument to toDouble() method.

QString str("8564.26495574");
bool ok = false;
qDebug() << str.toDouble(&ok);
qDebug() << ok;

// The output we get the following
// 8564.26
// true - that is, the error was not

In order to make the correct output, you must use the method of QString::arg() indicating the type of formatting and precission.

QString str("8564.26495574");

double a = 8564.26495574;
double b = str.toDouble();

qDebug() << QString("%1").arg(a, 0, 'f', 5);
qDebug() << QString("%1").arg(a, 0, 'g', 5);
qDebug() << QString("%1").arg(a, 0, 'e', 10);
qDebug() << QString("%1").arg(a, 0, 'g', 30);

qDebug() << QString("%1").arg(b, 0, 'f', 5);
qDebug() << QString("%1").arg(b, 0, 'g', 5);
qDebug() << QString("%1").arg(b, 0, 'e', 10);
qDebug() << QString("%1").arg(b, 0, 'g', 30);

As a result, we obtain the following output of qDebug():

"8564.26496"
"8564.3"
"8.5642649557e+3"
"8564.26495574000000488013029099"

"8564.26496"
"8564.3"
"8.5642649557e+3"
"8564.26495574000000488013029099"

In both cases, we obtain the identical result as here and there number is the same.

A few words about the types of formatting:

  • 'g' - It outputs a predetermined number of symbols starting from the largest digit number in the integer portion;
  • 'f' - It displays the specified number of characters with precision after the decimal point;
  • 'e' - It displays the specified number of characters with precision after the decimal point and indication of the number of hidden charges.

As you can see in the output there is a small error 8564.26495574000000488013029099 . This is connected with features of the mathematical apparatus of the computer on which the calculations are made. The capacity of the bit numbers in any computer is limited, so in the last decimal place rounding occurs, which causes the appearance of such options. This should be considered when accurate calculations.

Virtual hosting with 10 percent discount
Virtual hosting with 10 percent discount
EVILEG offers reliable hosting with a 10% discount for virtual hosting and 5% for VPS
Support the author Donate
  • #
  • Feb. 6, 2018, 9:19 a.m.

Добрый день, подскажите пожалуйста. Столкнулся с проблемой, парсю JSON получаю цифровые значения типа string, пример (QJsonValue(string, "0.0000000001")), делаю преобразование типа в double.

auto strToDouble = [] (const QString str) { return QString(str).toDouble(); };

На выходе у меня получается такое значение 1Е-10, каким образом мне получить значение 0.0000000001 в переменной double. Делать дополнительное преобразование в QML считаю не нормальным.

  • #
  • Feb. 6, 2018, 9:30 a.m.

Решение было найдено. В QML использовал метод JavaScript toFixed() Method, массив data_1[0].toFixed(10), 10 количество мне нужных знаков после запятой.

Comments

Only authorized users can post comments.
Please, Log in or Sign up
TT
June 13, 2019, 7:01 p.m.
Taimoor Tanweer

C++ - Test 001. The first program and data types

  • Result:66points,
  • Rating points-1
TT
June 13, 2019, 6:51 p.m.
Taimoor Tanweer

C++ - Test 002. Constants

  • Result:75points,
  • Rating points2
ВМ
June 13, 2019, 12:30 p.m.
Ваня Мороз

C++ - Test 001. The first program and data types

  • Result:100points,
  • Rating points10
Last comments
i
June 17, 2019, 6:10 a.m.
ingenfly

Только по осям xAxis2, уAxis2 значения начинаются с 0. Почему-то xAxis2 и xAxis не синхронизированы по данным. Ну и QCustomPlot последний.
June 16, 2019, 8:21 p.m.
Евгений Легоцкой

Добрый день. Ну точно также добавляете ту же самую информацию на ось xAxis2, только добавляете другое форматирование customPlot->xAxis2->setDateTimeFormat("hh:mm"); если я ...
EF
June 14, 2019, 1:56 p.m.
Egor Fomin

Спасибо за ваш ответ, у меня получилось реализовать это. Тем не менее появилась другая проблема, поэтому опять надеюсь на вашу помощь. Скажем, я уже выставил точки и они соеденены. Когда я нач...
d
June 13, 2019, 2:47 p.m.
damix

Можно классу, который описывает точку, добавить сигнал, который подавать (emit), когда точка перемещается (переопределить mouseMoveEvent или mouseReleaseEvent). Так вот эти сигналы у каждой из...
i
June 13, 2019, 2:09 p.m.
ingenfly

Здравствайте! Подскажите, пожалуйста: customPlot->xAxis2->setTickLabels(true); //Здесь включается отображение данных на оси xAxis2. а можно как-то продублировать информацию cus...
Now discuss on the forum
June 20, 2019, 9:30 a.m.
IscanderChe

Вернулся к этой задачке только-только, поэтому и не ответил ничего раньше.Как переопределить mouseReleaseEvent(QMouseEvent* event) у QTableView, если QTableView задан в ui? Или задавать QTabl...
I
June 19, 2019, 1:41 p.m.
Intruder

Всем добрый день. При разборе XML файла наткнулся на тег вот такого плана: <TagName attribute1="value1" attribute2="value2" /> При попытке проверить на наличие такого элеме...
June 19, 2019, 12:55 p.m.
Михаиллл

Скажите пожалуйста, как его в таком случае перемещать и удалять?
June 18, 2019, 7:50 p.m.
Дмитрий

Большое спасибо! SDK заработал.К сожалению удалось продвинутся только на один шаг. При сборке чистого проекта NDK выдаёт следующие ошибки C:\Android\ndk-bundle/toolchains/arm-linux-andr...
June 18, 2019, 4:59 p.m.
Михаиллл

Добрый день.В этом учебнике представлен код INSTALLED_APPS = ( ... 'rest_framework', 'snippets.apps.SnippetsConfig',) На строчке 'snippets.apps.SnippetsConf...
Looking for a Job?
25,000.00 руб. - 30,000.00 руб.
Разработчик Qt/C++
Barnaul, Altai Krai, Russia

For registered users on the site there is a minimum amount of advertising

EVILEG
About
Services
Join us
© EVILEG 2015-2019
Recommend hosting TIMEWEB