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. C Casting Problem

C Casting Problem

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestion
5 Posts 3 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 seen the term Fixed_32 for a data item with MSB = 1 and LSB = 1/2**31 ; Max = 1.0 and Min = -1.0 with units of semicircles (used for Latitude and Longitude) I did think this was a float to the IEEE-754 Floating-Point Representation. However the 3rd party that is reading some data via a message structure cannot see the same value. I mistaken the term Fixed_32 as a standard float but it is a 32 bit int in the message. The scalling is:-

    #define BEARING_SCALING 4.65661287307739E-10

    typedef struct ReceiveMessage
    {
    unsigned int msgNumber; // Msg number
    int msgPosLat; // Msg latitude
    int msgPosLong; // Msg longitude
    unsigned int msgQuality; // Msg quality
    }positionData

    #define BEARING_SCALING 4.65661287307739E-10

    However I get a crash when I try to load the value (the Latitude was declared as a double and I tried to cast to the int and vice versa. Code:

    // Note 180 is used to scale up from semicircles to degrees
    double lat = 55.55;
    positionData.msgPosLat = (int)(lat/(BEARING_SCALING * 180));

    // and the other way for reading:-

    lat = (double)( positionData.msgPosLat) * BEARING_SCALING * 180;

    What is going wrong please, is it the oder of casting or do I need to use fix point stuff?

    L M 2 Replies Last reply
    0
    • A Andy202

      I have seen the term Fixed_32 for a data item with MSB = 1 and LSB = 1/2**31 ; Max = 1.0 and Min = -1.0 with units of semicircles (used for Latitude and Longitude) I did think this was a float to the IEEE-754 Floating-Point Representation. However the 3rd party that is reading some data via a message structure cannot see the same value. I mistaken the term Fixed_32 as a standard float but it is a 32 bit int in the message. The scalling is:-

      #define BEARING_SCALING 4.65661287307739E-10

      typedef struct ReceiveMessage
      {
      unsigned int msgNumber; // Msg number
      int msgPosLat; // Msg latitude
      int msgPosLong; // Msg longitude
      unsigned int msgQuality; // Msg quality
      }positionData

      #define BEARING_SCALING 4.65661287307739E-10

      However I get a crash when I try to load the value (the Latitude was declared as a double and I tried to cast to the int and vice versa. Code:

      // Note 180 is used to scale up from semicircles to degrees
      double lat = 55.55;
      positionData.msgPosLat = (int)(lat/(BEARING_SCALING * 180));

      // and the other way for reading:-

      lat = (double)( positionData.msgPosLat) * BEARING_SCALING * 180;

      What is going wrong please, is it the oder of casting or do I need to use fix point stuff?

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

      I think it works like this: the latitude in degrees ranges from -90 to +90 (and not -180 to +180). the encoding used is 32-bit fixed integers with an implied scale factor, so the full range [-90,+90] gets mapped onto the full integer range. So you want +90 represented by the largest positive 32-bit integer (which equals 2^31 minus one, or 0x7FFFFFFF), hence:

      int fixed32(double lat) {
      lat=lat/90.;
      lat=lat*0x7FFFFFFF;
      return (int)lat;
      }

      Notes: 1. this code will never return the minimum value (0x80000000). For -90 it results in 0x80000001 which is a consequence of [-90,+90] being symmetric around zero, whereas the integer range [0x80000000, 0x7FFFFFFF] isn't. 2. I tend to avoid magic constants, such as the 4.65661287307739E-10 you had. I prefer to write them in a way that reveals what they stand for. Your value stems from 1.0/0x7FFFFFFF 3. I doubt the code you have shown would crash at all. lat/(BEARING_SCALING * 180) will not exceed the acceptable range for integers (and your formula being wrong by a factor of 2 IMO only reassures this). (positionData.msgPosLat) * BEARING_SCALING * 180) may incur an integer overflow (again due to the factor of 2), but normally those get swallowed. So I expect if anything bombs, it must be the code that follows after you used these formulas, mainly the latitude going all the way up to +180. :)

      Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

      Please use <PRE> tags for code snippets, and update CP Vanity to V2.0 if you haven't already.

      modified on Thursday, December 9, 2010 3:45 PM

      A 1 Reply Last reply
      0
      • L Luc Pattyn

        I think it works like this: the latitude in degrees ranges from -90 to +90 (and not -180 to +180). the encoding used is 32-bit fixed integers with an implied scale factor, so the full range [-90,+90] gets mapped onto the full integer range. So you want +90 represented by the largest positive 32-bit integer (which equals 2^31 minus one, or 0x7FFFFFFF), hence:

        int fixed32(double lat) {
        lat=lat/90.;
        lat=lat*0x7FFFFFFF;
        return (int)lat;
        }

        Notes: 1. this code will never return the minimum value (0x80000000). For -90 it results in 0x80000001 which is a consequence of [-90,+90] being symmetric around zero, whereas the integer range [0x80000000, 0x7FFFFFFF] isn't. 2. I tend to avoid magic constants, such as the 4.65661287307739E-10 you had. I prefer to write them in a way that reveals what they stand for. Your value stems from 1.0/0x7FFFFFFF 3. I doubt the code you have shown would crash at all. lat/(BEARING_SCALING * 180) will not exceed the acceptable range for integers (and your formula being wrong by a factor of 2 IMO only reassures this). (positionData.msgPosLat) * BEARING_SCALING * 180) may incur an integer overflow (again due to the factor of 2), but normally those get swallowed. So I expect if anything bombs, it must be the code that follows after you used these formulas, mainly the latitude going all the way up to +180. :)

        Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

        Please use <PRE> tags for code snippets, and update CP Vanity to V2.0 if you haven't already.

        modified on Thursday, December 9, 2010 3:45 PM

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

        Thanks Luc, the Longitude (-180 to +180) has the same scaling. I can get the code running OK on Windwos but when ported to Unix (using a Gnu complier) the program bombs out. Debuggin a bit limited hence the use of Windows for the development.

        L 1 Reply Last reply
        0
        • A Andy202

          Thanks Luc, the Longitude (-180 to +180) has the same scaling. I can get the code running OK on Windwos but when ported to Unix (using a Gnu complier) the program bombs out. Debuggin a bit limited hence the use of Windows for the development.

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

          Andy202 wrote:

          the Longitude (-180 to +180) has the same scaling.

          not sure what you are saying here. the longitude range has to cover 360 degrees (either -180 to +180 or 0 to +360), so it could be latitude uses the same scale factor, but then your opening statement (about MIN and MAX) isn't accurate for latitude. OTOH if the scale factor is different for lat and lon, that would justify why the 180 (or 360) isn't incorporated in the magic constant.

          Andy202 wrote:

          when ported to Unix (using a Gnu complier) the program bombs out.

          A different compiler may generate different code, e.g. it could emit code that does check for overflows at run-time. [ADDED] So far you have not specified where in the code it crashes. [/ADDED] I can only suggest you: 1. include some logging statements so you can watch the numbers till the program crashes. 2. perform some unit tests (a simple loop over the range of interest should be easily implemented). Taken together, that will clarify what goes on. :)

          Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

          Please use <PRE> tags for code snippets, and update CP Vanity to V2.0 if you haven't already.

          modified on Thursday, December 9, 2010 5:17 PM

          1 Reply Last reply
          0
          • A Andy202

            I have seen the term Fixed_32 for a data item with MSB = 1 and LSB = 1/2**31 ; Max = 1.0 and Min = -1.0 with units of semicircles (used for Latitude and Longitude) I did think this was a float to the IEEE-754 Floating-Point Representation. However the 3rd party that is reading some data via a message structure cannot see the same value. I mistaken the term Fixed_32 as a standard float but it is a 32 bit int in the message. The scalling is:-

            #define BEARING_SCALING 4.65661287307739E-10

            typedef struct ReceiveMessage
            {
            unsigned int msgNumber; // Msg number
            int msgPosLat; // Msg latitude
            int msgPosLong; // Msg longitude
            unsigned int msgQuality; // Msg quality
            }positionData

            #define BEARING_SCALING 4.65661287307739E-10

            However I get a crash when I try to load the value (the Latitude was declared as a double and I tried to cast to the int and vice versa. Code:

            // Note 180 is used to scale up from semicircles to degrees
            double lat = 55.55;
            positionData.msgPosLat = (int)(lat/(BEARING_SCALING * 180));

            // and the other way for reading:-

            lat = (double)( positionData.msgPosLat) * BEARING_SCALING * 180;

            What is going wrong please, is it the oder of casting or do I need to use fix point stuff?

            M Offline
            M Offline
            mbue
            wrote on last edited by
            #5

            normally c-compilers cast from left to right (implicit). if yours don't - cast yourself (explicit): positionData.msgPosLat = (int)(lat/(BEARING_SCALING * 180.0)); // (int)(double/(double*double)) AND lat = ( (double)positionData.msgPosLat * (BEARING_SCALING * 180.0)); // (double*(double*double)) // hint: don't define twice (BEARING_SCALING) have a nice day.

            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