Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Data Type Conversions

Data Type Conversions

Scheduled Pinned Locked Moved C / C++ / MFC
data-structureshelpquestion
8 Posts 4 Posters 0 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.
  • A Offline
    A Offline
    Andy202
    wrote on last edited by
    #1

    I have been trying to interface with a software program which uses a message made up of a 20 word array of unsigned shorts;

    unsigned short messageData[20];

    I have been trying to use data from a home GPS system which includes Lat and Long and heading.; these have been converted from strings to floats. e.g. float lat, long, heading; My problem is that as I know the scaling factors and least Sig Bit (LSB) for the lat, long and heading in the messageData buffer; e.g. For lat and long LSB = 8.377E-08; Twos complement - 32 bits Max/ Min -180 to +180 For Heading LSB 0.00549306; Twos complement - 16 bits Max/ Min -180 to +180 Setting the heading:- unsigned short heading = (unsigned short)(newHeading/0.00549306); messageData[10] = heading; Getting the heading:-

    bool negative;
    unsigned short currentField = messageData[10];
    if(currentField & 0x8000)
    {
    // Set the negative flag
    negative = true;
    }
    else
    negative = false;
    float heading = (currentField & 0x7FFF) * g_nScalings[wordPos];
    if(negative)
    heading = -(180 - heading);

    But this does not work as I expected; am I missing something? As for the 32 bit latitude, I was going to this:- Setting the Latitude:-

    union
    {
    int lat_long;
    unsigned short buff[2];
    }convert;

    unsigned short highWord, lowWord;
    int newData = (int)(fEngValue/8.377E-08);

    convert.lat_long = newData;
    highWord = convert.buff[1];
    lowWord = convert.buff[0];

    I need to get and set data in the message that is of type unsigned short and use in my program as scaled floats. Any suggestions please.

    C M L 3 Replies Last reply
    0
    • A Andy202

      I have been trying to interface with a software program which uses a message made up of a 20 word array of unsigned shorts;

      unsigned short messageData[20];

      I have been trying to use data from a home GPS system which includes Lat and Long and heading.; these have been converted from strings to floats. e.g. float lat, long, heading; My problem is that as I know the scaling factors and least Sig Bit (LSB) for the lat, long and heading in the messageData buffer; e.g. For lat and long LSB = 8.377E-08; Twos complement - 32 bits Max/ Min -180 to +180 For Heading LSB 0.00549306; Twos complement - 16 bits Max/ Min -180 to +180 Setting the heading:- unsigned short heading = (unsigned short)(newHeading/0.00549306); messageData[10] = heading; Getting the heading:-

      bool negative;
      unsigned short currentField = messageData[10];
      if(currentField & 0x8000)
      {
      // Set the negative flag
      negative = true;
      }
      else
      negative = false;
      float heading = (currentField & 0x7FFF) * g_nScalings[wordPos];
      if(negative)
      heading = -(180 - heading);

      But this does not work as I expected; am I missing something? As for the 32 bit latitude, I was going to this:- Setting the Latitude:-

      union
      {
      int lat_long;
      unsigned short buff[2];
      }convert;

      unsigned short highWord, lowWord;
      int newData = (int)(fEngValue/8.377E-08);

      convert.lat_long = newData;
      highWord = convert.buff[1];
      lowWord = convert.buff[0];

      I need to get and set data in the message that is of type unsigned short and use in my program as scaled floats. Any suggestions please.

      C Offline
      C Offline
      CPallini
      wrote on last edited by
      #2

      Could you please elaborate a bit. :confused: Could you post inputs, wrong and expected outputs? :)

      If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
      This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
      [My articles]

      1 Reply Last reply
      0
      • A Andy202

        I have been trying to interface with a software program which uses a message made up of a 20 word array of unsigned shorts;

        unsigned short messageData[20];

        I have been trying to use data from a home GPS system which includes Lat and Long and heading.; these have been converted from strings to floats. e.g. float lat, long, heading; My problem is that as I know the scaling factors and least Sig Bit (LSB) for the lat, long and heading in the messageData buffer; e.g. For lat and long LSB = 8.377E-08; Twos complement - 32 bits Max/ Min -180 to +180 For Heading LSB 0.00549306; Twos complement - 16 bits Max/ Min -180 to +180 Setting the heading:- unsigned short heading = (unsigned short)(newHeading/0.00549306); messageData[10] = heading; Getting the heading:-

        bool negative;
        unsigned short currentField = messageData[10];
        if(currentField & 0x8000)
        {
        // Set the negative flag
        negative = true;
        }
        else
        negative = false;
        float heading = (currentField & 0x7FFF) * g_nScalings[wordPos];
        if(negative)
        heading = -(180 - heading);

        But this does not work as I expected; am I missing something? As for the 32 bit latitude, I was going to this:- Setting the Latitude:-

        union
        {
        int lat_long;
        unsigned short buff[2];
        }convert;

        unsigned short highWord, lowWord;
        int newData = (int)(fEngValue/8.377E-08);

        convert.lat_long = newData;
        highWord = convert.buff[1];
        lowWord = convert.buff[0];

        I need to get and set data in the message that is of type unsigned short and use in my program as scaled floats. Any suggestions please.

        M Offline
        M Offline
        Mike the Red
        wrote on last edited by
        #3

        If you're dealing with floats that have been converted to strings, just convert them back to floats. The unsigned short is the same as wchar_t - you should be able to use an explicit cast to 'convert' between them. _wtof() converts a wchar_t string to a double, which you can then cast to a float, if the value is withing the range of type float. _ecvt() converts a double (or float cast to double) to a wchar_t string, though you'll have to do some string manipulation to put the sign and/or decimal in the indicated place(s). Both functions are in <stdlib.h>. Hope this is useful, MZR

        A 1 Reply Last reply
        0
        • A Andy202

          I have been trying to interface with a software program which uses a message made up of a 20 word array of unsigned shorts;

          unsigned short messageData[20];

          I have been trying to use data from a home GPS system which includes Lat and Long and heading.; these have been converted from strings to floats. e.g. float lat, long, heading; My problem is that as I know the scaling factors and least Sig Bit (LSB) for the lat, long and heading in the messageData buffer; e.g. For lat and long LSB = 8.377E-08; Twos complement - 32 bits Max/ Min -180 to +180 For Heading LSB 0.00549306; Twos complement - 16 bits Max/ Min -180 to +180 Setting the heading:- unsigned short heading = (unsigned short)(newHeading/0.00549306); messageData[10] = heading; Getting the heading:-

          bool negative;
          unsigned short currentField = messageData[10];
          if(currentField & 0x8000)
          {
          // Set the negative flag
          negative = true;
          }
          else
          negative = false;
          float heading = (currentField & 0x7FFF) * g_nScalings[wordPos];
          if(negative)
          heading = -(180 - heading);

          But this does not work as I expected; am I missing something? As for the 32 bit latitude, I was going to this:- Setting the Latitude:-

          union
          {
          int lat_long;
          unsigned short buff[2];
          }convert;

          unsigned short highWord, lowWord;
          int newData = (int)(fEngValue/8.377E-08);

          convert.lat_long = newData;
          highWord = convert.buff[1];
          lowWord = convert.buff[0];

          I need to get and set data in the message that is of type unsigned short and use in my program as scaled floats. Any suggestions please.

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          1. could you give some actual data samples, where both the short representation and the real value are known? four or more pairs would be good. 2. for 32-bit data, for sure there only is one sign bit, so both halves need different treatment. :)

          Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


          I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.


          A 1 Reply Last reply
          0
          • M Mike the Red

            If you're dealing with floats that have been converted to strings, just convert them back to floats. The unsigned short is the same as wchar_t - you should be able to use an explicit cast to 'convert' between them. _wtof() converts a wchar_t string to a double, which you can then cast to a float, if the value is withing the range of type float. _ecvt() converts a double (or float cast to double) to a wchar_t string, though you'll have to do some string manipulation to put the sign and/or decimal in the indicated place(s). Both functions are in <stdlib.h>. Hope this is useful, MZR

            A Offline
            A Offline
            Andy202
            wrote on last edited by
            #5

            Sorry not made myself very clear. Forget about strings to floats thats OK. I need to cast from a float to a unsigned short using the information about the format about the unsigned short; e.g. top bit is sign, LSB is the scaling. Now if I run my code with a heading set to 3.45 this sets the unsigned short to 0xB999 which is not what I expected. Or looking at it the other way if the value of the unsigned short is 0x0001 then this would represent heading = (float)0x0001 * LSB. The messageData holds the data as unsigned shorts which need to be processed on Get and Set if that makes sense. For Lat and Long two elements are used, for heading just one.

            1 Reply Last reply
            0
            • L Luc Pattyn

              1. could you give some actual data samples, where both the short representation and the real value are known? four or more pairs would be good. 2. for 32-bit data, for sure there only is one sign bit, so both halves need different treatment. :)

              Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


              I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.


              A Offline
              A Offline
              Andy202
              wrote on last edited by
              #6

              Just to recap and get things right in my mind; if a heading value is represented as an unsigned short (16 bits) with bit 1 = 0.000030517578125; so the range is -1 to + 1 and if we multiple by 180 we get -180 to +180 degrees - more useful Now for a test I set heading to 3.45 then the following occures. 3.45/0.000030517578125 = 1B999 in Hex; but as we can only store 16 bits in the unsigned short the debugger shows B999 as the value. Now when I come to decode that vaue via:- B999 * 0.000030517578125 = 1.44998169 which is wrong and if x 180 to get into degrees then get 260.99. Now for reading another value say, e.g. the value is 1234hex then we get:- 1234Hex * 0.000030517578125 = 0.14221191 and if we convert into degrees then get 0.14221191 * 180 = 25.598144 degrees. Hope this helps to explan what I am trying to do.

              L 1 Reply Last reply
              0
              • A Andy202

                Just to recap and get things right in my mind; if a heading value is represented as an unsigned short (16 bits) with bit 1 = 0.000030517578125; so the range is -1 to + 1 and if we multiple by 180 we get -180 to +180 degrees - more useful Now for a test I set heading to 3.45 then the following occures. 3.45/0.000030517578125 = 1B999 in Hex; but as we can only store 16 bits in the unsigned short the debugger shows B999 as the value. Now when I come to decode that vaue via:- B999 * 0.000030517578125 = 1.44998169 which is wrong and if x 180 to get into degrees then get 260.99. Now for reading another value say, e.g. the value is 1234hex then we get:- 1234Hex * 0.000030517578125 = 0.14221191 and if we convert into degrees then get 0.14221191 * 180 = 25.598144 degrees. Hope this helps to explan what I am trying to do.

                L Offline
                L Offline
                Luc Pattyn
                wrote on last edited by
                #7

                I see you ignored all I asked and said. If I understood what you meant correctly, then: the LSB value is 360/0x10000 (approx 0.00549) assuming a monotonous binary representation (as opposed to e.g. sign+mantissa), we get:

                0x7FFF = almost 180
                0x0000 = 0
                0x8000 = -180

                3.45 --> 3.45*0x10000/360 = 628 = 0x0274 -3.45 --> -3.45*0x10000/360 = -628 = 0xFD8C :|

                Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


                I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.


                A 1 Reply Last reply
                0
                • L Luc Pattyn

                  I see you ignored all I asked and said. If I understood what you meant correctly, then: the LSB value is 360/0x10000 (approx 0.00549) assuming a monotonous binary representation (as opposed to e.g. sign+mantissa), we get:

                  0x7FFF = almost 180
                  0x0000 = 0
                  0x8000 = -180

                  3.45 --> 3.45*0x10000/360 = 628 = 0x0274 -3.45 --> -3.45*0x10000/360 = -628 = 0xFD8C :|

                  Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


                  I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.


                  A Offline
                  A Offline
                  Andy202
                  wrote on last edited by
                  #8

                  Sorry Luc, as you may have noticed I am getting more confused, but think getting there from your last post. One field in this array was height which ranged from 0 to 10,000, but the LSB was 0.5, and the sign not used; e.g. bit 15 was data. So if you had 0000 0000 0000 1000 which is 8 then that represented 4 meters. I got this working and then turned to see why the heading and lat/long were not! But with heading which did use the sign and had a range of -1 to +1 and a very small LSB. May next question is are they a formula to handle these types of conversions. Just for a Windows platforn with the VS environment. Still need to sort out the two unsigned short Lat and Long.

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups