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 216 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 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