Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Convert quint16 to float number

Convert quint16 to float number

Scheduled Pinned Locked Moved Solved C++ Gurus
10 Posts 4 Posters 8.0k Views
  • 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.
  • beeckscheB Offline
    beeckscheB Offline
    beecksche
    wrote on last edited by kshegunov
    #1

    Hi everybody,
    my question is not really Qt specific, but my search through the internet wasn't successful.

    I get a quint16 number (representing a floating number) from a function and want to convert it to a floating number https://en.wikipedia.org/wiki/Half-precision_floating-point_format

    Like:

    float quint16ToFloat(quint16 value)
    {
     // insert magic stuff
    
     return myFloat;
    }
    

    Can anybody help?

    Thanks

    [Moved to C++ Gurus ~kshegunov]

    kshegunovK 1 Reply Last reply
    0
    • beeckscheB beecksche

      Hi everybody,
      my question is not really Qt specific, but my search through the internet wasn't successful.

      I get a quint16 number (representing a floating number) from a function and want to convert it to a floating number https://en.wikipedia.org/wiki/Half-precision_floating-point_format

      Like:

      float quint16ToFloat(quint16 value)
      {
       // insert magic stuff
      
       return myFloat;
      }
      

      Can anybody help?

      Thanks

      [Moved to C++ Gurus ~kshegunov]

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #2

      Hi,
      Try something along these lines:

      float quint16ToFloat(quint16 value)
      {
          union  {
              quint16 v;
              struct  {
                  qint8 sign : 1;
                  qint8 exponent: 5;
                  qint16 fraction: 10;
              } frep;
          } halfPrecisionFloat;
      
          union  {
              float v;
              struct  {
                  qint8 sign : 1;
                  qint8 exponent: 8;
                  qint16 fraction: 23;
              } frep;
          } singlePrecisionFloat;
      
          halfPrecisionFloat.v = value;
          singlePrecisionFloat.frep.sign = halfPrecisionFloat.frep.sign;
          singlePrecisionFloat.frep.exponent = halfPrecisionFloat.frep.exponent;
          singlePrecisionFloat.frep.fraction = halfPrecisionFloat.frep.fraction;
      
          return singlePrecisionFloat.v;
      }
      

      ... or alternatively ...

      float quint16ToFloat(quint16 value)
      {
          quint32 result = (static_cast<quint32>(value & 0x8000) << 16) | (static_cast<quint32>(value & 0x7FF) << 13);
          return *reinterpret_cast<float *>(&result); // ... don't ask ...
      }
      

      Warning:
      You should bear in mind, however, that the first snippet is relying on the C++ compiler following the C99 standard, not the C++11 on unions (which is the case in my experience, but still ...!). In the latter reading an uninitialized field from a union is undefined, the former has defined behavior. The second code snippet isn't all roses either, it allows for alignment specific problems (because of the nasty reinterpret at the end).

      EDIT:
      I've corrected an error in the second snippet. The mantissa bits should be aligned to the rightmost possible significant bit as they're inverse powers (i.e. 1/2, 1/4, 1/8 etc).

      Kind regards.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      5
      • ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #3

        Depending on your platform there might be more options, e.g. compiler extensions.

        1 Reply Last reply
        4
        • beeckscheB Offline
          beeckscheB Offline
          beecksche
          wrote on last edited by
          #4

          @Wieland
          The application will be run on windows, x86 architecture.

          I found some good papers like http://blog.schmorp.de/data/binary16/fasthalffloatconversion.pdf

          I didn't expect that the conversion is such difficult.

          The data i will receive are temperatures of a modus tcp register from this module

          In my case the temperature range is between +20°C to +500°C.

          kshegunovK jsulmJ 2 Replies Last reply
          0
          • beeckscheB beecksche

            @Wieland
            The application will be run on windows, x86 architecture.

            I found some good papers like http://blog.schmorp.de/data/binary16/fasthalffloatconversion.pdf

            I didn't expect that the conversion is such difficult.

            The data i will receive are temperatures of a modus tcp register from this module

            In my case the temperature range is between +20°C to +500°C.

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

            @beecksche said in Convert quint16 to float number:

            I found some good papers like http://blog.schmorp.de/data/binary16/fasthalffloatconversion.pdf

            Good find. I've forgotten about the special values ... *_* sounds silly for a person bragging about knowing floating point arithmetic inside out ... :)

            I didn't expect that the conversion is such difficult.

            It's not a native type, that's the reason, you don't have hardware support for half-precision fp numbers.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            1
            • beeckscheB Offline
              beeckscheB Offline
              beecksche
              wrote on last edited by beecksche
              #6

              @kshegunov

              So i have just implemented the formula given here

              float quint16ToFloat(const quint16 & value)
              {
                  int sign = value >> 15 & 1;
              
                  int exponent = 0;
                  for (int i = 10; i <=14; i++)
                      exponent |= (value >> i & 1) << (i - 10);
              
                  float mantissa = 0;
                  for (int i = 0; i <= 9; i++)
                      mantissa +=  (value >> i & 1) * qPow(2.0, -1.0 * (9 - i + 1));
              
                  if (exponent >= 1 && exponent <= 30)
                      mantissa +=1;
              
                  if (exponent == 0 && mantissa == 0)
                      return 0.0;
              
                  if (exponent == 31 && mantissa == 0)
                      ; //infinity
              
                  if (exponent == 31 && mantissa != 0)
                      ; // Nan
              
                  qDebug() << "Sign: " << sign;
                  qDebug() << "Exponent: " << exponent - 15;
                  qDebug() << "Mantissa: " << mantissa;
              
                  return qPow(-1.0, sign) * qPow(2.0, exponent - 15) * mantissa;
              }
              
              int main(int argc, char *argv[])
              {
                  QCoreApplication a(argc, argv);
              
                  quint16 value = 20384; // Operand A = 30.5 = 0 10011 1110100000 = 20384
              
                  qDebug() << "quint16: " << value << "float: " << quint16ToFloat(value);
              
                  return a.exec();
              }
              

              Output:
              Sign: 0
              Exponent: 4
              Mantissa: 1.90625
              quint16: 20384 float: 30.5

              Here is a online converter and i get the same results http://oletus.github.io/float16-simulator.js/

              It seems to work.

              1 Reply Last reply
              1
              • beeckscheB beecksche

                @Wieland
                The application will be run on windows, x86 architecture.

                I found some good papers like http://blog.schmorp.de/data/binary16/fasthalffloatconversion.pdf

                I didn't expect that the conversion is such difficult.

                The data i will receive are temperatures of a modus tcp register from this module

                In my case the temperature range is between +20°C to +500°C.

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @beecksche I'm wondering why they use floating point numbers for that (which are not even standardised!)? Why not use uint16 and represent 1°C as lets say 10?
                Then 20,5 would be 205.
                I hope they do not develop anything for financial area using floating point numbers :-)

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                beeckscheB kshegunovK 2 Replies Last reply
                2
                • jsulmJ jsulm

                  @beecksche I'm wondering why they use floating point numbers for that (which are not even standardised!)? Why not use uint16 and represent 1°C as lets say 10?
                  Then 20,5 would be 205.
                  I hope they do not develop anything for financial area using floating point numbers :-)

                  beeckscheB Offline
                  beeckscheB Offline
                  beecksche
                  wrote on last edited by beecksche
                  #8

                  @jsulm
                  You're right! I misinterpreted the documentation of the temperature module.
                  Today i've tested it and get the wrong temperatures.

                  In the module you can set a temperature resolution: 0.01 °C or 0.1 °C. The value i get is a 16 bit value, the 15th bit is the sign and the other 15 bit (0 - 14) represent the temperature depending in the set resolution.

                  Resolution Data Bits Sign Value Temperature
                  0.01 2046 0 000011111111110 + 2046 20.46
                  0.1 204 0 000000011001100 + 204 20.4
                  0.1 32972 1 000000011001100 - 204 -20.4

                  So it isn't that difiicult as i thought at the beginning. But now i know to convert a 16 bit float value ;-)

                  Thanks for help!

                  1 Reply Last reply
                  1
                  • jsulmJ jsulm

                    @beecksche I'm wondering why they use floating point numbers for that (which are not even standardised!)? Why not use uint16 and represent 1°C as lets say 10?
                    Then 20,5 would be 205.
                    I hope they do not develop anything for financial area using floating point numbers :-)

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by
                    #9

                    @jsulm said in Convert quint16 to float number:

                    I hope they do not develop anything for financial area using floating point numbers :-)

                    As far as my understanding goes, fixed point arithmetic is still the technique of choice for financial (or rather accounting) applications.

                    @beecksche said in Convert quint16 to float number:

                    But now i know to convert a 16 bit float value ;-)

                    Not that you will ever need it ... ;)
                    ... but I'm glad you found a solution.

                    Kind regards.

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    2
                    • beeckscheB Offline
                      beeckscheB Offline
                      beecksche
                      wrote on last edited by
                      #10

                      Since Qt 5.9.0 there's a qfloat16 class to handle half-float values https://wiki.qt.io/New_Features_in_Qt_5.9 and https://doc.qt.io/qt-5/qfloat16.html.

                      The class is based on the algorithms described in the paper http://blog.schmorp.de/data/binary16/fasthalffloatconversion.pdf

                      1 Reply Last reply
                      3

                      • Login

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