Long Integer being cast as integer

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • dinklebaga
    New Member
    • Feb 2009
    • 14

    Long Integer being cast as integer

    Hi All,
    I am writing a function at the moment to calculate the value of an byte offset for a floppy disk image but for some reason the long integer I am using to store this value is signed despite explicitly declaring it as unisgned. Also where the function value is return to, if this is given the correct value there is no problem so it appears to be limited to this function. Any ideas?
    Code is:
    Code:
    find_offset(sect, cyl, hd)
    char sect, hd, cyl;
    {
        char sectorsize = 512;
        unsigned long offset = 0;
        offset = (cyl*2)*18;
        printf("offset = %d\n", offset);
    	if(hd == 1)
    	{
            offset = (offset + 18);
    	}
    	printf("offset = %d\n", offset);
    	offset = (offset + sect);
    	printf("offset = %d\n", offset);
    	offset = (offset * 512);
    	printf("offset = %d\n", offset);
    	offset = (offset - 512);
    	printf("offset = %d\n", offset);
    	return(offset);
    }
    Value of Sect: 3
    Value of Cyl: 6
    Value of Hd: 1

    value that should be returned by this is 120832 but actual value is -10240
    Thanks,
    Dinklebaga
  • donbock
    Recognized Expert Top Contributor
    • Mar 2008
    • 2427

    #2
    Originally posted by dinklebaga
    Code:
        char cyl = 6;
        unsigned long offset = 0;
        offset = (cyl*2)*18;
        printf("offset = %d\n", offset);
    The "%d" conversion specifier promises printf that you passed a signed int -- but you didn't!
    I suggest you review the printf documentation to find the proper conversion specifier.

    Comment

    • Savage
      Recognized Expert Top Contributor
      • Feb 2007
      • 1759

      #3
      I don't see the return type of the function.Is it unsigned long too?

      Comment

      • dinklebaga
        New Member
        • Feb 2009
        • 14

        #4
        Originally posted by Savage
        I don't see the return type of the function.Is it unsigned long too?
        Regardless of the return type I am not getting the correct result. Is there an issue using a 16 bit memory model with forcing unsigned long integers to be signed? Just to let you know that I am using the digital mars c/c++ compiler with the 16bit dos extender. no matter what I do with this compiler setup it always uses the 16th bit as the sign value despite casting them as unsigned. Have you ever encountered these issues before?
        Regards,
        Dinklebaga

        Comment

        • JosAH
          Recognized Expert MVP
          • Mar 2007
          • 11453

          #5
          Originally posted by dinklebaga
          Have you ever encountered these issues before?
          Read the very first reply in this thread: you are printing your unsigned long value as if it were a simple signed int (%d). You simply lied to the printf function. Check your manual how to print a long int and an unsigned int.

          kind regards,

          Jos

          Comment

          • dinklebaga
            New Member
            • Feb 2009
            • 14

            #6
            Originally posted by JosAH
            Read the very first reply in this thread: you are printing your unsigned long value as if it were a simple signed int (%d). You simply lied to the printf function. Check your manual how to print a long int and an unsigned int.

            kind regards,

            Jos
            I have changed the printf statement to %u in accordance with the manual but it is still giving the wrong value even when explicitly declaring the result as 120832. It comes out as 55296

            Comment

            • donbock
              Recognized Expert Top Contributor
              • Mar 2008
              • 2427

              #7
              Originally posted by dinklebaga
              Code:
                  char sectorsize = 512;
              The value "512" is too large to fit in a char. You get integer overflow.
              Originally posted by dinklebaga
              Code:
              find_offset(sect, cyl, hd)
              char sect, hd, cyl;
              {
                  ...
                  unsigned long offset = 0;
                  offset = (cyl*2)*18;
              In the assignment to "offset", "cyl" is promoted to an int and the computation is performed on int's, then the result is cast to an unsigned long. If you are worried about overflow in the computation then you need to command the compiler to use long arithmetic:
              Code:
                  offset = ((unsigned long)cyl)*2*18;
              Argument "cyl" has a signed type. What would you like to see happen if the caller passes a negative value? Why not declare all of the function arguments as "unsigned int" or "unsigned long" or "size_t"?

              By the way, if sectorsize is truly a fixed constant, then it should be defined as follows (except change the type from char to something else):
              Code:
                  static const char sectorsize = 512;

              Comment

              • donbock
                Recognized Expert Top Contributor
                • Mar 2008
                • 2427

                #8
                Originally posted by dinklebaga
                I have changed the printf statement to %u in accordance with the manual but it is still giving the wrong value even when explicitly declaring the result as 120832. It comes out as 55296
                %u is the conversion specifier for an "unsigned int". You want to print an "unsigned long". You need a slightly different conversion specifier.

                Comment

                • JosAH
                  Recognized Expert MVP
                  • Mar 2007
                  • 11453

                  #9
                  Originally posted by dinklebaga
                  I have changed the printf statement to %u in accordance with the manual but it is still giving the wrong value even when explicitly declaring the result as 120832. It comes out as 55296
                  Try "%lu", the ell stands for "long" and the u stands for "unsigned".

                  kind regards,

                  Jos

                  Comment

                  Working...