Thread: Unsigned Long returning signed value

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    2

    Angry Unsigned Long returning signed value

    Hi All,
    I don't know if any of you have used the digital mars c compiler but I am having issues with some of the functions within it. i would use something else but i need the 16-bit environment to control disk access at kernel level (INT 13H BIOS Command) The compiler when given a number larger than 2^15 is returning a signed value (16th bit is the sign value) even when it is explicitly declared as unsigned.
    This isn't restricted to the 16bit mode as i have been using the 32bit large memory model in the compiler as well. But ideally i need to have this working in 16bit.
    Any idea?
    Thanks,
    Dinklebaga

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Signed and unsigned values are only different in two situations:
    1. Translation between binary and string in either direction (e.g printf, scanf, strtol, etc).
    2. Comparisons of greater/lesser (e.g 2^15 > 2^14 in unsigned, but not in signed values).

    So if you say you "get a signed value in an unsigned variable", I suspect you are using %d to print it, and you should be using %u or %x, which are unsigned formats.

    Or you are comparing two unsigned values and getting the wrong result because the compiler generates the wrong comparison code.

    Without seeing the code, it would be impossible to comment on what is correct and what isn't. But my guess is that you are simply using a "binary to string" conversion that uses the wrong interpretation.

    Also: If you are running in a Windows "DOS box", INT 13H is not a low-level function, it just pretends to be, it still uses the OpenFile/ReadFile/WriteFile/CloseFile I/O functions that any Windows program would use. Of course, if you are using plain DOS or some other real-mode OS, then yes, you are calling directly to the real BIOS code (unless it has somehow been replaced by some other driver code, which is entirely possible in DOS).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Mar 2009
    Posts
    2
    Quote Originally Posted by matsp View Post
    Signed and unsigned values are only different in two situations:
    1. Translation between binary and string in either direction (e.g printf, scanf, strtol, etc).
    2. Comparisons of greater/lesser (e.g 2^15 > 2^14 in unsigned, but not in signed values).

    So if you say you "get a signed value in an unsigned variable", I suspect you are using %d to print it, and you should be using %u or %x, which are unsigned formats.

    Or you are comparing two unsigned values and getting the wrong result because the compiler generates the wrong comparison code.

    Without seeing the code, it would be impossible to comment on what is correct and what isn't. But my guess is that you are simply using a "binary to string" conversion that uses the wrong interpretation.

    Also: If you are running in a Windows "DOS box", INT 13H is not a low-level function, it just pretends to be, it still uses the OpenFile/ReadFile/WriteFile/CloseFile I/O functions that any Windows program would use. Of course, if you are using plain DOS or some other real-mode OS, then yes, you are calling directly to the real BIOS code (unless it has somehow been replaced by some other driver code, which is entirely possible in DOS).

    --
    Mats
    Mats,
    Below is a small section of code that the problem is occurring in:
    Code:
    find_offset(sect, cyl, hd)
    unsigned long sect, hd, cyl;
    {
        char sectorsize = 512;
        unsigned long offset = 0;
        sect = 3;
        hd = 1;
        cyl = 6;
        offset = (cyl*2)*18;
        printf("offset = %d\n", offset);
    	if(hd == 1)
    	{
            offset = (offset + 18);
    	}
    	printf("offset = %u\n", offset);
    	offset = (offset + sect);
    	printf("offset = %u\n", offset);
    	offset = (offset * 512);
    	printf("offset = %u\n", offset);
    	offset = (offset - 512);
    	printf("offset = %u\n", offset);
    	return(offset);
    the printf statements previously contained %d values as you pointed out but once consulting the manual and changing these to %u I am no longer getting negative values but instead i am now getting the wrong value. In the last printf statement i should have the value of 120832 but instead i am getting 55296.
    Also as you pointed out the DOS environment does pretend to use INT13h as a low level call but I am using assembler language within an ASM function to make the calls to the disk.

    Regards,
    Dinklebaga

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Perhaps you need to have another look in the manual. LONG integers require a "%ld" or "%lu" formatting.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. xor linked list
    By adramalech in forum C Programming
    Replies: 23
    Last Post: 10-14-2008, 10:13 AM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. Need Help Please
    By YouShallNotPass in forum C++ Programming
    Replies: 3
    Last Post: 08-22-2006, 11:22 AM
  4. Please STICKY this- vital to MSVC 6 dev - BASETSD.h
    By VirtualAce in forum Game Programming
    Replies: 11
    Last Post: 03-15-2005, 09:22 AM

Tags for this Thread