简体   繁体   中英

How negative numbers are stored in memory? How to know the bit representation?

I am aware of MSB, LSB, sign and magnitude one's and two's complement etc. Now, I would like to know if I am writing and program which does some bit manipulation, How would I check the actual bit level data in memory?

ie int a = -1; How would I know if it is 1001 or 1110 or 1111 in a 4-bit representation?

How do I figure out the method my implementation uses to represent negative numbers?

I am looking for some way to examine the bit level data of a C program.

My current platform is Ubuntu 12.04 LTS. Once again, the question is not about how it is done. It is about how to find out or justify that it is done in some way.

union { int i; unsigned u; } x;
x.i = -1;

Now xu gives you the unsigned integer with the same bits. There is only one way to represent unsigned numbers so you can just examine that. (As a hint: it is most likely two's complement.)

printf("%x\n", x.u);

The above print statement will print out the hexadecimal representation of the unsigned integer, which you can use to determine the bits.

By applying bitwise operations. Eg you can test if the n-th bit is set by performing a & (1<<n) (apply it in a loop, then you got the whole number).

EDIT: But this does only work, when the internal representation is binary. When a different system (eg the Russians had in the ´70s a computer with ternary logic and number system, and the Polish a system on negabinary basis) is used this will not give the right internal used format.

One easy method is to inspect the variable in a debugger like this:

(gdb) p/t var

p/t says to print the binary representation.

void showBit(int num, int nBit)//nBit -> number of bits
{
    unsigned int temp = 1<<(nBit-1), i;

    for(i=0; i<nBit; ++i)
    {
        printf("%d ", ((num&temp)?1:0) );
        temp = temp>>1;
    }
    printf("\n");
}  

you can use this function to print the binary representation. see it on ideone .

In C, negative numbers are expressed in a 2's compliment format for signed numbers.

This is done, to avoid any compiler(I,e it works even if int is 8 bit or 16 bit or 32 bit and so on).

In your case if you compiler interprets int as 8 bit then 1111 1111 will be stored. As soon as the first bit(sign bit) is 1 compiler understands that it is a negative number and understands the number has to be the two's compliment. which is nothing but 0000 0001, with a negative sign

You can even make the use of union .

union num
{
    int f;
    char c[4];
};

void printBinary(union num u)
{
    int i,t,j;

    for(i=sizeof(u)-1; i>=0; i--)
    {
            for(j=0,t=128; j<8; j++,t>>=1)
                    printf("%d",(u.c[i]&t)?1:0);
            printf(" ");
    }
}

int main() 
{
    union num n;
    n.f=10;
    printBinary(n);
    return 0;
}

see here: http://ideone.com/i9YCt

How do I figure out the method my implementation uses to represent negative numbers?

Here is how:

unsigned int a = -1;
swicth (a & 3U)
{
    case 3:
        printf("two's complement\n");
        break;

    case 2:
        printf("one's complement\n");
        break;

    case 1:
        printf("sign and magnitude\n");
        break;

    default:
        printf("compiler broken\n");
        break; 
}

The ultimate answer is actually in your compiler documentation which is required to document which signed representation is used. For example, for gcc :

Whether signed integer types are represented using sign and magnitude, two's complement, or one's complement, and whether the extraordinary value is a trap representation or an ordinary value (C99 6.2.6.2)

GCC supports only two's complement integer types, and all bit patterns are ordinary values

http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html

The positive and negative numbers identified by the 8th bit of the number. if 8th bit is 0 it is positive otherwise negative.

For example x=8
so In binary x=8=0000 1000 (It is positive number, so eight bit is 0 from right to left)

For negative x = -8
The negative numbers are represented in binary using 2's complement usually.
 so x = -8 

step 1 binary of        8 = 0000 1000
step 2 1's complement     = 1111 0111
step 3 2's complement     =         1
                         y = 1111 1000 =248(so it represents the negative because 8th bit is 1 then it follows the below formula)

The formula for getting negative value from binary representation is 2^8-y
 so 256-248=8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM