При розробці програмного забезпечення на Qt довелося зіткнутися з одним нюансом при виведенні чисел з плаваючою комою через qDebug(). Проблема полягає в тому, що виводяться не всі символи після коми. Тим самим грішить і висновок std::cout .
Подібний user case може виникнути у такій ситуації:
У вас є об'єкт QString, який містить якесь число "8564.26495574", яке ми переводимо в число з плаваючою точкою за допомогою методу toDouble(), і перевіряємо результат за допомогою висновку qDebug() , але незадача , Виведення виявляється помилковим.
QString str("8564.26495574"); qDebug() << str.toDouble(); // В выводе получаем -> 8564.26
Хоча насправді ми отримуємо абсолютно правильне число, тобто рядок було отримано число 8564.26495574 , просто висновок qDebug() показує заокруглений результат.
Те саме можна спостерігати, якщо спробувати просто вивести значення числа double у qDebug().
double a = 8564.26495574; qDebug() << a; // В выводе получаем -> 8564.26
Переконатися в тому, що жодних помилок не відбувається при конвертуванні числа з QString у double можна, скориставшись змінною bool, покажчик на яку передається як аргумент на метод toDouble().
QString str("8564.26495574"); bool ok = false; qDebug() << str.toDouble(&ok); qDebug() << ok; // В выводе получим следующее // 8564.26 // true - то есть ошибок не было
Для того, щоб зробити коректний висновок, необхідно скористатися методом QString::arg() із зазначенням типу форматування та точності.
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);
В результаті отримаємо наступний висновок qDebug():
"8564.26496" "8564.3" "8.5642649557e+3" "8564.26495574000000488013029099" "8564.26496" "8564.3" "8.5642649557e+3" "8564.26495574000000488013029099"
В обох випадках отримуємо ідентичний результат, оскільки і там і там число одне й те саме.
Пару слів про типи форматування:
- 'g' - виводить вказану кількість символів починаючи з найбільшого розряду в цілій частині числа;
- 'f' - виводить вказану кількість символів з точністю після коми;
- 'e' - виводить вказану кількість символів з точністю після коми та вказівкою числа прихованих розрядів.
Як бачите у висновку є невелика похибка 8564.2649557400000488013029099. Це вже пов'язано з особливостями математичного апарату того комп'ютера, на якому виробляються розрахунки. Місткість розрядності чисел в будь-якому комп'ютері обмежена, тому в останньому розряді після коми відбувається округлення, яке викликає появу подібних варіантів числа. Це необхідно враховувати за точних розрахунків.
Добрый день, подскажите пожалуйста. Столкнулся с проблемой, парсю JSON получаю цифровые значения типа string, пример (QJsonValue(string, "0.0000000001")), делаю преобразование типа в double.
На выходе у меня получается такое значение 1Е-10, каким образом мне получить значение 0.0000000001 в переменной double. Делать дополнительное преобразование в QML считаю не нормальным.
Решение было найдено. В QML использовал метод JavaScript toFixed() Method, массив data_1[0].toFixed(10), 10 количество мне нужных знаков после запятой.