Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-31906

QJsonDocument::toJson() wrongly uses the default double to QString conversion and produces data loss

    XMLWordPrintable

Details

    Description

      Hi, this one is really a showstopper!

      I found out that the double to QString conversion used by QJsonDocument::toJson() is the default one, i.e. it only guarantees 6 digits precision, which is an unbelievable limitation.

      Considering that I'm using JSON to parse and produce data used by online services and that often double values are used for resources indexing, you can very well immagine that this is a frightening limit.

      Anyway, I think that defaulting to 6 digits precision is not the safest option today (with lots of cases where converting doubles to strings and back is necessary), in fact I tend to find it more "faulting" than "de-faulting".

      Here is some code for you to check what I'm talking about:

      #include <QtCore>
      
      int main(int argc, char *argv[])
      {
          double d1(100000001.0);
          // d1 stores 100000001.0
          qDebug() << d1;
          // qDebug() incorrectly prints:
          // 1e+08
          QString s1(QString("%1").arg(d1));
          // s1 incorrectly stores "1e+08"
          qDebug() << s1;
          // qDebug() correctly prints:
          // "1e+08"
          // but the stored value is WRONG
          double d2= s1.toDouble();
          // d2 is correctly converted from "1e+08" to 100000000
          // but the stored value is WRONG
          qDebug() << (d1 == d2);
          // qDebug()correctly prints:
          // false
          // but the test should be TRUE
      
          QJsonObject jObject;
          jObject.insert("a nice double value", QJsonValue(d1));
          QJsonDocument jDocument1(jObject);
          qDebug() << jDocument1.toJson();
          // The QJsonDocument stores a WRONG value, and qDebug() prints:
          // "{
          //     "a nice double value": 1e+08
          // }
          // "
          QJsonDocument jDocument2= QJsonDocument::fromJson(jDocument1.toJson());
          double d3= jDocument2.object().value("a nice double value").toDouble();
          qDebug() << d3;
          // d3 is correctly converted from "1e+08" to 100000000
          // but the stored value is WRONG
          qDebug() << (d1 == d3);
          // qDebug()correctly prints:
          // false
          // but the test should be TRUE
      
          QString s2= QString::number(d1, 'f');
          // s2 correctly stores "100000001.000000"
          double d4= s2.toDouble();
          // d4 correctly stores 100000001
          qDebug() << (d1 == d4);
          // qDebug()correctly prints:
          // true
      
          QString s3= QString::number(d1, 'g', 12);
          // s2 correctly stores "100000001"
          double d5= s3.toDouble();
          // d4 correctly stores 100000001
          qDebug() << (d1 == d5);
          // qDebug()correctly prints:
          // true
      
          QString s4= QString::number(d1, 'e', 12);
          // s2 correctly stores "1.000000010000e+08"
          double d6= s4.toDouble();
          // d4 correctly stores 100000001
          qDebug() << (d1 == d6);
          // qDebug()correctly prints:
          // true
      
          QJsonValue jValue1(d1);
          double d7= jValue1.toDouble();
          qDebug() << (d1 == d7);
          // qDebug()correctly prints:
          // true
      
          return 0;
      }
      

      Attachments

        Activity

          People

            liaqi Liang Qi
            albert76 Albert
            Votes:
            3 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: