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. Endianess of QByteArray ?
Forum Updated to NodeBB v4.3 + New Features

Endianess of QByteArray ?

Scheduled Pinned Locked Moved General and Desktop
11 Posts 4 Posters 16.6k Views 1 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.
  • D Offline
    D Offline
    deleted28
    wrote on last edited by
    #1

    How can i get the float Pi value of both castings below, by only modifying
    the line 13 @ result_big = reinterpret_cast<const float>(ba_bigPi.data()); @

    Not the QByteArray creation above !
    I assume that qFromBigEndian , qFromLittleEndian might do this job but i do
    not know how to apply.

    2nd Question:
    Do i need the static const char array to get the data correctly into the QByteArray ?

    @ float result_big, result_lit;

        static const char bigEn_Pi[] = {0x40, 0x49, 0x0F, 0xDB};
        static const char litEn_Pi[] = {0xDB, 0x0F, 0x49, 0x40};
    
        QByteArray ba_bigPi = QByteArray::fromRawData(bigEn_Pi, sizeof(bigEn_Pi));
        QByteArray ba_litPi = QByteArray::fromRawData(litEn_Pi, sizeof(litEn_Pi));
    
        qDebug() << (sizeof(result_big) == ba_bigPi.size());    // true
        qDebug() << ba_bigPi.toHex().toUpper();             // "40490FDB"
        qDebug() << ba_litPi.toHex().toUpper();             // "DB0F4940"
    
        result_big = *reinterpret_cast<const float*>(ba_bigPi.data());
    
        //    qFromBigEndian
        //    qFromLittleEndian
    
        result_lit = *reinterpret_cast<const float*>(ba_litPi.data());
    
        qDebug() << result_big;
        qDebug() << result_lit;
    
        qDebug() << QSysInfo::BigEndian;
        qDebug() << QSysInfo::LittleEndian;
    

    // output:
    // true
    // "40490FDB"
    // "DB0F4940"
    // -4.03315e+16
    // 3.14159
    // 0
    // 1@

    thank you :)

    1 Reply Last reply
    0
    • JeroentjehomeJ Offline
      JeroentjehomeJ Offline
      Jeroentjehome
      wrote on last edited by
      #2

      Hi,
      I'm not really sure what you want to do with the Endian stuff, but IYAM don't mess around with it unless you really need to. Qt and almost all other programming languages and most small ucontrollers use little endian, so stick to that.
      The conversion of a float to a bytearray is:
      QByteArray QByteArray::number(double n, char f = 'g', int prec = 6) [static]
      and
      toDouble() if you want to reconstruct the float.

      Greetz, Jeroen

      1 Reply Last reply
      0
      • D Offline
        D Offline
        deleted28
        wrote on last edited by
        #3

        Jeroen,

        i get little- and big- endian Bytestreams from a unusual device and need to
        process the data. Only floats coming in as data (no doubles) , rest is setting and protocol stuff i can manage already. For this reason i want to use a function like
        @float MainWindow::QBA2Float(QByteArray _ba, bool _bigEnd) {@
        If _bigEnd is false it should interprete the incoming QByteArray as liitleEndian. I might copy this QByteArray inside the function to an temporary QByteArray with reverse endianess.
        On the other hand I'm also curious how the suggested solution is implemented correctly* (qFromBigEndian , qFromLittleEndian)*

        1 Reply Last reply
        0
        • JeroentjehomeJ Offline
          JeroentjehomeJ Offline
          Jeroentjehome
          wrote on last edited by
          #4

          Hi,
          Using floats or doubles to be transported across devices is highly discouraged. A float may be constructed in different formats across different cpu's. Using a QByteArray should do the trick, simply switch the last with first byte ;-), but then the float construction might get lost and very strange values are 'decoded'.
          The QtEndian class clearly states that only integral values may be used! So, do so ;-)
          If you need some sort of float values to be transported, simply multiply the start value by 1000 or more and send data, then read in and divide again at the receiving end.
          Again, sending floats is NOT possible in a guaranteed way.

          Greetz, Jeroen

          1 Reply Last reply
          0
          • JKSHJ Offline
            JKSHJ Offline
            JKSH
            Moderators
            wrote on last edited by
            #5

            http://comments.gmane.org/gmane.comp.lib.qt.user/8565

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            1 Reply Last reply
            0
            • tomasz3dkT Offline
              tomasz3dkT Offline
              tomasz3dk
              wrote on last edited by
              #6

              Hi,
              Try to use QDataStream it works for me
              @
              float result_big, result_lit;
              static const char bigEn_Pi[] = {0x40, 0x49, 0x0F, 0xDB};
              static const char litEn_Pi[] = {0xDB, 0x0F, 0x49, 0x40};
              QByteArray ba_bigPi = QByteArray::fromRawData(bigEn_Pi, sizeof(bigEn_Pi));
              QByteArray ba_litPi = QByteArray::fromRawData(litEn_Pi, sizeof(litEn_Pi));
              QDataStream str(&ba_bigPi,QIODevice::ReadOnly);
              str.setFloatingPointPrecision(QDataStream::SinglePrecision);
              str.setByteOrder(QDataStream::BigEndian);
              QDataStream str2(&ba_litPi,QIODevice::ReadOnly);
              str2.setFloatingPointPrecision(QDataStream::SinglePrecision);
              str2.setByteOrder(QDataStream::LittleEndian);
              str >> result_big;
              str2 >> result_lit;
              qDebug()<<result_big;
              qDebug()<<result_lit;@
              Of course you must remember about floatingpointprecision to set it properly. Better way to send data with different endiness is to multiply and divide float to int and send it as int. Just as Jeroentje@home wrote.

              1 Reply Last reply
              0
              • D Offline
                D Offline
                deleted28
                wrote on last edited by
                #7

                Thank you diabolic !

                Here are some results i found and works for me.
                Maybe its of general interest, so i post here.
                I set some more comments as usual for better understanding.
                Any suggestions and remarks welcome.

                especially line 28 seems to work :

                @void MainWindow::on_pb_swap1_clicked()
                {

                // pi-big: "40490FDB"
                // on lit system:
                // dec int = 1 078 530 011
                // bin = 0b 01000000010010010000111111011011
                // float = -4.0331460896358400E16

                // Pi-lit: "DB0F4940" (Hexadecimal is little-endian (right-to-left)
                // on lit-system:
                // dec int = 3 675 212 096
                // bin = 0b 11011011000011110100100101000000 (negative as signed int)
                // float = 3.1415927410125732421875

                float result;
                quint32 tni_ip;
                
                QString str = "40490FDB";
                bool ok;
                quint32 pi_int = str.toUInt(&ok,16);
                
                result = *reinterpret_cast<float*>(&pi_int); // cast to little endian
                qDebug() << "1: " << result;    //  3.14159
                
                str = "DB0F4940";
                pi_int = str.toUInt(&ok,16);
                qToBigEndian<quint32>(quint32(pi_int),
                reinterpret_cast<unsigned char*>(&tni_ip));
                
                result = *reinterpret_cast<float*>(&tni_ip);
                qDebug() << "2: " << result;    // -4.03315e+16
                

                }

                void MainWindow::on_pb_swap2_clicked()
                {

                QByteArray ba = QByteArray::fromHex("FF0F40490FDBFF1FDB0F4940FFFF");
                
                float f;
                quint32 tmp_i;
                QByteArray ba_part = ba.mid(2, 4);
                
                QDataStream s1(ba_part); s1 >> tmp_i;
                f = *reinterpret_cast<float*>(&tmp_i);
                qDebug() << "1: " << f;
                
                ba_part = ba.mid(8, 4);
                QDataStream s2(ba_part);
                s2.setByteOrder(QDataStream::LittleEndian);
                s2 >> tmp_i;
                f = *reinterpret_cast<float*>(&tmp_i);
                qDebug() << "2: " << f ;
                

                }@

                output for both functions:
                @1: 3.14159
                2: 3.14159 @

                Is something similar like the following possible ?

                QDataStream >> float >> quint16 >> quint16 >> float

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  deleted28
                  wrote on last edited by
                  #8

                  answering last question myself :)

                  @void MainWindow::on_pb_split1_clicked()
                  {

                  QByteArray ba = QByteArray::fromHex("FF0F40490FDBFF1FDB0F4940FFFF");
                  
                  quint16 sh1, sh2, sh3;
                  quint32 int1, int2;
                  float f1,f2;
                  
                  QDataStream str_1(ba);
                  str_1 >> sh1 >> int1 >> sh2 >> int2 >> sh3;
                  qDebug() << sh1 << int1 << sh2 << int2 << sh3;
                  
                  QDataStream str_2(ba);
                  str_2.setFloatingPointPrecision(QDataStream::SinglePrecision);
                  str_2  >> sh1 >> f1 >> sh2 >> f2 >> sh3;
                  qDebug()  << sh1 << f1 << sh2 << f2 << sh3;
                  

                  // output: "65295 1078530011 65311 3675212096 65535"
                  // ( FF0F 40490FDB FF1F DB0F4940 FFFF )

                  // output: 65295 3.14159 65311 -4.03315e+16 65535

                  }@

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    deleted28
                    wrote on last edited by
                    #9

                    to Moderator/ Admin:
                    Please let me know if my kind of using the forum is unwanted

                    Now trying to stream the data into a structure:
                    I assume i need an "friend operator>> overloading" but i do not know how to.

                    in mainwindow.h, public:
                    @#pragma pack(1)
                    typedef struct {
                    quint8 sta; // 'CC'
                    quint16 len; // size = 29
                    quint8 cmd; // command type
                    quint16 pref1; // prefix 1
                    float temp; // temperature (pi IEEE754 bigEndian)
                    quint16 pref2; // prefix 2
                    float press; // pressure (pi IEEE754 littleEndian
                    quint16 h_res; // 2 zero bytes reserve
                    char h_dat[255]; // 0 to 255 bytes , "Hello World" here 11
                    } packet;
                    #pragma pack()@

                    mainwindow.cpp:
                    @void MainWindow::on_pb_split3_clicked()
                    {

                    // CC 1D00 05 FF0F 40490FDB FF1F DB0F4940 0000 48656C6C6F20576F726C64
                    // 29* 5 bE Pi lE Pi 0 Hello World (11) *lE !!

                    QByteArray ba = QByteArray::fromHex("CC1D0005FF0F40490FDBFF1FDB0F4940000048656C6C6F20576F726C64");
                    QDataStream stream(&ba, QIODevice::WriteOnly);
                    
                    packet *serPac = new packet();
                    
                    qDebug() << sizeof(*serPac) ;  // 273-255 = 29-11 = 18
                    
                    ...
                    stream ---&gt;>  serPac ???            
                    ...
                    
                    qDebug() << serPac->sta;
                    qDebug() << serPac->temp;
                    

                    }@

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      deleted28
                      wrote on last edited by
                      #10

                      One step further
                      Remains problems with the trailing data (payload)
                      I need some help for line 11, 24 and 39. Thank you.

                      in mainwindow.h, public:
                      @#pragma pack(1)
                      struct Packet {
                      quint8 sta; // 'CC'
                      quint16 len; // size = 29
                      quint8 cmd; // command type
                      quint16 pref1; // prefix 1
                      float temp; // temperature (pi IEEE754 bigEndian)
                      quint16 pref2; // prefix 2
                      float press; // pressure (pi IEEE754 littleEndian
                      quint16 res; // 2 zero bytes reserve
                      QByteArray dat; // "Hello World" here 11

                          friend QDataStream &operator<<(QDataStream &out, const Packet &_packet)
                          {
                              out.setFloatingPointPrecision(QDataStream::SinglePrecision);
                              out << _packet.sta;
                              out << _packet.len;
                              out << _packet.cmd;
                              out << _packet.pref1;
                              out << _packet.temp;
                              out << _packet.pref2;
                              out << _packet.press;
                              out << _packet.res;
                              out << _packet.dat;
                              return out;
                          }
                      
                          friend QDataStream &operator>>(QDataStream &in, Packet &_packet)
                          {
                              in.setFloatingPointPrecision(QDataStream::SinglePrecision);
                              in >> _packet.sta;
                              in >> _packet.len;
                              in >> _packet.cmd;
                              in >> _packet.pref1;
                              in >> _packet.temp;
                              in >> _packet.pref2;
                              in >> _packet.press;
                              in >> _packet.res;
                              in >> _packet.dat;
                              return in;
                          }
                      };
                      

                      #pragma pack()@

                      mainwindow.cpp:
                      @void MainWindow::on_pb_split3_clicked()
                      {

                      // CC 1D00 05 FF0F 40490FDB FF1F DB0F4940 0000 48656C6C6F20576F726C64
                      // 204 29* 5 bE Pi lE Pi 0 Hello World (11) *lE !!
                      // 29 Bytes

                      QByteArray ba = QByteArray::fromHex("CC1D0005FF0F40490FDBFF1FDB0F4940000048656C6C6F20576F726C64");
                      
                      QDataStream stream(&ba, QIODevice::ReadWrite);
                      
                      struct Packet serPac;           // = new Packet();
                      qDebug() << sizeof(serPac) ;    // output 22 ?
                      
                      stream >> serPac;
                      
                      qDebug() << serPac.sta;     // CC = 204
                      qDebug() << serPac.len;     // 1D00 (001D) = 7424 (29)
                      qDebug() << serPac.cmd;     // 05 = 5
                      qDebug() << serPac.pref1;   // FF0F = 65295
                      qDebug() << serPac.temp;    // 40490FDB = 3.14159 ieee754, 32
                      qDebug() << serPac.pref2;   // FF1F = 65311
                      qDebug() << serPac.press;   // DB0F4940 = -4.03315e+16
                      qDebug() << serPac.res;     // 00 00 = 0
                      qDebug() << serPac.dat;     // ???
                      

                      }
                      @
                      output:
                      22
                      204
                      7424
                      5
                      65295
                      3.14159
                      65311
                      -4.03315e+16
                      0
                      ""

                      1 Reply Last reply
                      0
                      • D Offline
                        D Offline
                        deleted28
                        wrote on last edited by
                        #11

                        OK
                        as for line 39 in above mainwindow.h this solution seems to work:

                        substitute @in >> _packet.dat;@ by
                        @// in >> _packet.dat;
                        quint8 iByte;
                        while (!in.atEnd()) {
                        in >> iByte;
                        _packet.dat.append(iByte);
                        }@

                        is this serious work or rubbish ?

                        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