Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QSettings and float numeric type do not play nice together

QSettings and float numeric type do not play nice together

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 5 Posters 217 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    wareagle
    wrote last edited by
    #1

    I am attempting to read and write float values from/to a text file. Using C++.
    The data type within the software is defined as: 'typedef float Float32_t;' I inherited this and
    it is not changeable.

    Results in the text file look like this: "@QVariant(\0\0\0\x87=\xcc\xcc\xcd", which is not acceptable.

    Here is the 'write' method:

    void writeCustom(const QString &Key, const Float32_t &val)
    {
    QSettings settings(mFilePath, QSettings::IniFormat);
    settings.setValue(Key, QVariant(static_cast<float>(val)));
    }

    This same approach works for double types.
    Please weigh in. Thanks

    JonBJ 1 Reply Last reply
    0
    • W wareagle

      I am attempting to read and write float values from/to a text file. Using C++.
      The data type within the software is defined as: 'typedef float Float32_t;' I inherited this and
      it is not changeable.

      Results in the text file look like this: "@QVariant(\0\0\0\x87=\xcc\xcc\xcd", which is not acceptable.

      Here is the 'write' method:

      void writeCustom(const QString &Key, const Float32_t &val)
      {
      QSettings settings(mFilePath, QSettings::IniFormat);
      settings.setValue(Key, QVariant(static_cast<float>(val)));
      }

      This same approach works for double types.
      Please weigh in. Thanks

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote last edited by JonB
      #2

      @wareagle said in QSettings and float numeric type do not play nice together:

      Results in the text file look like this: "@QVariant(\0\0\0\x87=\xcc\xcc\xcd", which is not acceptable.

      So that I understand. What is "not acceptable"? Assuming that value is correct, and deserializes correctly, that is all Settings is supposed to do. Are you saying something like you want to impose requirements on its output (to a file or registry) such that it is human-readable to you?

      1 Reply Last reply
      0
      • Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote last edited by
        #3

        Also when double works fine - simply store them as double.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        JonBJ 1 Reply Last reply
        0
        • Christian EhrlicherC Christian Ehrlicher

          Also when double works fine - simply store them as double.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote last edited by
          #4

          @Christian-Ehrlicher
          I agree, but his problem will be that it will deserialize as a QVariant(double) where he presumably requires it to be QVariant(float)? So he may need to do some massaging.

          Christian EhrlicherC 1 Reply Last reply
          0
          • JonBJ JonB

            @Christian-Ehrlicher
            I agree, but his problem will be that it will deserialize as a QVariant(double) where he presumably requires it to be QVariant(float)? So he may need to do some massaging.

            Christian EhrlicherC Online
            Christian EhrlicherC Online
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote last edited by
            #5

            @JonB said in QSettings and float numeric type do not play nice together:

            @Christian-Ehrlicher
            I agree, but his problem will be that it will deserialize as a QVariant(double) where he presumably requires it to be QVariant(float)? So he may need to do some massaging.

            I don't understand - QSettings returns a QVariant. QVariant has toFloat()...

            And this works fine for me with Qt6.11

            double dbl = 1.0;
            float flt = 1.0f;
            QSettings settings("D:/tmp.ini", QSettings::IniFormat);
            settings.setValue("dbl", dbl);
            settings.setValue("flt", flt);
            

            -->

            [General]
            dbl=1
            flt=1
            

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            JonBJ 1 Reply Last reply
            0
            • Christian EhrlicherC Christian Ehrlicher

              @JonB said in QSettings and float numeric type do not play nice together:

              @Christian-Ehrlicher
              I agree, but his problem will be that it will deserialize as a QVariant(double) where he presumably requires it to be QVariant(float)? So he may need to do some massaging.

              I don't understand - QSettings returns a QVariant. QVariant has toFloat()...

              And this works fine for me with Qt6.11

              double dbl = 1.0;
              float flt = 1.0f;
              QSettings settings("D:/tmp.ini", QSettings::IniFormat);
              settings.setValue("dbl", dbl);
              settings.setValue("flt", flt);
              

              -->

              [General]
              dbl=1
              flt=1
              
              JonBJ Offline
              JonBJ Offline
              JonB
              wrote last edited by
              #6

              @Christian-Ehrlicher
              If you have

              float flt = 1.0f;
              settings.setValue("flt", flt);
              // stored in a .ini file as
              flt=1
              

              then I don't know where/why the OP comes up with @QVariant(\0\0\0\x87=\xcc\xcc\xcd in the output/.ini/text file in the first place? Unless by any chance it depends on the value in flt rather than a simple 1.

              W 1 Reply Last reply
              0
              • W Offline
                W Offline
                wareagle
                wrote last edited by
                #7

                The only real requirement is that the float value must be human readable in order for a user to be able to change it within the file. Like => 0.1234

                JonBJ 1 Reply Last reply
                0
                • W wareagle

                  The only real requirement is that the float value must be human readable in order for a user to be able to change it within the file. Like => 0.1234

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote last edited by JonB
                  #8

                  @wareagle
                  You're not supposed to do this, but OK :) So please recheck by trying @Christian-Ehrlicher 's example verbatim, where he is showing floats being stored readably. Try with other values, like whatever your value was, to make sure. If you don't find same result as him please report your Qt version & platform.

                  1 Reply Last reply
                  0
                  • JonBJ JonB

                    @Christian-Ehrlicher
                    If you have

                    float flt = 1.0f;
                    settings.setValue("flt", flt);
                    // stored in a .ini file as
                    flt=1
                    

                    then I don't know where/why the OP comes up with @QVariant(\0\0\0\x87=\xcc\xcc\xcd in the output/.ini/text file in the first place? Unless by any chance it depends on the value in flt rather than a simple 1.

                    W Offline
                    W Offline
                    wareagle
                    wrote last edited by
                    #9

                    @JonB The 'starting' value in the text file was 0.1. After reading and then writing it to file it showed the '@Variant..... (I guess binary value, not sure) in the file.

                    JonBJ 1 Reply Last reply
                    0
                    • W wareagle

                      @JonB The 'starting' value in the text file was 0.1. After reading and then writing it to file it showed the '@Variant..... (I guess binary value, not sure) in the file.

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote last edited by JonB
                      #10

                      @wareagle
                      Could you please change @Christian-Ehrlicher 's example to use 0.1 as the value. Show us the verbatim code and the output. Use 0.1 for the double too. Then wait for someone like Christian (not me) to re-test.

                      Please do this before dealing with reading text and converting back, if that is what you do. One thing at a time! Let's see only what the problem writing a float to a .ini is, standalone. Then, depending, show the shortest possible complete, standalone code demonstrating your issue.

                      If you don't care about this and doubles do work, don't forget like Christian said you can save as a double and deal with assigning it to float on reading.

                      W 1 Reply Last reply
                      0
                      • JonBJ JonB

                        @wareagle
                        Could you please change @Christian-Ehrlicher 's example to use 0.1 as the value. Show us the verbatim code and the output. Use 0.1 for the double too. Then wait for someone like Christian (not me) to re-test.

                        Please do this before dealing with reading text and converting back, if that is what you do. One thing at a time! Let's see only what the problem writing a float to a .ini is, standalone. Then, depending, show the shortest possible complete, standalone code demonstrating your issue.

                        If you don't care about this and doubles do work, don't forget like Christian said you can save as a double and deal with assigning it to float on reading.

                        W Offline
                        W Offline
                        wareagle
                        wrote last edited by
                        #11

                        @JonB My fall back is doing this processing as a type double, which I already know works. My original question relates to why does float not work? Which no one seems to know. Is this a known issue with QSettings or what? I showed the exact code and the exact output within the file. Qt version 5.2.1. Platform is RHEL 8 Virtual Machine within VMWare.

                        JonBJ 1 Reply Last reply
                        0
                        • W wareagle

                          @JonB My fall back is doing this processing as a type double, which I already know works. My original question relates to why does float not work? Which no one seems to know. Is this a known issue with QSettings or what? I showed the exact code and the exact output within the file. Qt version 5.2.1. Platform is RHEL 8 Virtual Machine within VMWare.

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote last edited by JonB
                          #12

                          @wareagle
                          You did not show the full code, because although we saw the final output we did not see what the float value serialized actually was. Which means I cannot repro it. We also saw Christian's complete example, which did work.

                          Qt version 5.2.1.

                          Are you aware just how old that version is (a decade)? Nobody here will be able to try on that, I suspect? That may be your final answer as to why it does not work, and you may have to use double if that works with that version.

                          At least as of 7 years ago see https://stackoverflow.com/questions/55044655/why-is-qtsettings-storing-floats-in-a-weird-mode-what-am-missing . For your version that is the "answer" --- or someone's best guess at the reason. Sounds like it may have changed in more recent versions.

                          1 Reply Last reply
                          1
                          • Axel SpoerlA Offline
                            Axel SpoerlA Offline
                            Axel Spoerl
                            Moderators
                            wrote last edited by
                            #13

                            QSettings is a pretty robust class which has its weaknesses.
                            IMHO it tries to trade off type safety versus human readability.
                            If I need waterproof numeric types in settings, never store them directly.
                            Either I transform them to a string (which is also human readable).
                            If I need it 100% safe, I use the QDataStream << and >> operators and store the result in settings as a QByteArray.
                            That's not human readable, but 100% type safe.

                            Qt version 5.2.1

                            I think Noah used this version in his shipyard, and it was outdated when he set sails....
                            How about 6.8 for instance?

                            Software Engineer
                            The Qt Company, Oslo

                            1 Reply Last reply
                            0
                            • Kent-DorfmanK Offline
                              Kent-DorfmanK Offline
                              Kent-Dorfman
                              wrote last edited by Kent-Dorfman
                              #14

                              @Axel-Spoerl beat me to it, but quit messing with QVariant, then read/write your INI file as text, since INI is traditionally suppose to be a human readable format in the first place...and use normal stream read/write operations in text mode. This is also important since text mode negates possible issues with endianness of numerical storage.

                              The dystopian literature that served as a warning in my youth has become an instruction manual in my elder years.

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved