C - converting to 2s complement

被刻印的时光 ゝ 提交于 2020-01-24 16:57:22

问题


I've decided to do it this way

  • flip numbers 0=1, 1=0
  • add 1 to LSB
  • if carry, loop until array[i]==0

But I'm stuck on the last point; how can I say that in a conditional loop?


回答1:


You are talking about extended arithmetic. Most processors have carry-out and overflow results from every addition operation, but C does not provide access to them.

Your problem is that numbers get longer as they get bigger. If you're at the last bit you have, and you need to carry out, you need another bit! That means you need to reallocate the array of bits (if you are using an array).

Of course, a more practical solution is to use native integers rather than individual bits, since your processor already handles two's-complement quite nicely. Then, you know that adding one results in a carry-out if the original number is equal to (unsigned) -1. The fundamental problem remains; if you need to carry out of the last unsigned you need to allocate another.




回答2:


So you you store your number as an array of ints, which represent bits. In the code example you attached you forgot to increment the i variable, and to check if it exceeded the size of your array.

You could write something like this (I assume the size of the array is 5):

for (i = 0; i < 5; i++)
{
    if (array1[i] == 1)
        array1[i] = 0;
    else // we found a 0
        array1[i] = 1;
        break;
}



回答3:


I'm not quite sure what you're doing, but maybe this will help:

#define countof(x) (sizeof(x) / sizeof(x[0]))

// an 8-bit number
int byte[8] = {0, 1, 1, 0, 1, 1, 1, 0}; // 1 = on, 0 = off

// flip all bits
for (size_t i = 0; i < countof(byte); ++i)
{
    byte[i] = !byte[i];
}

// add one
for (size_t i = 0; i < countof(byte); ++i)
{
    if (byte[i]) // if on
    {
        byte[i] = 0; // "add 1, reset to zero", and carry (no break)
    }
    else // if off
    {
        byte[i] = 1; // turn on
        break; // nothing to carry, stop adding
    }

}

(I don't know how to push you in the right direction without just explaining the code, sorry. I think you're close enough this is still helpful.)

You see, when you add one, if the bit is already one, reset it to zero, and continue along the bits. If the bit is zero, set it to one, then break out of the loop. (Nothing to carry, so we're done adding.)

Hope that helps. By the way, you'll note the bits are being stored "backwards" in the code above. The LSB is at index 0.




回答4:


You can do 2's complement in a much easier way like bellow:

  • go unchanged till you find an 1.
  • just after getting the first 1, flip the next coming 0's to 1 and 1's to Zeros and continue doing this. if the MSB becomes 0, it means overflow occurred.

you can check the validity of the algorithm by yourself. and the implementation should be like bellow:

// an 8-bit number
int number[8] = {0, 1, 1, 1, 0, 1, 0, 0};
int i;
bool gotFirstOne = false;

// flip bits after you first encountered an 1
for (i = 0; i < 8; i++)
{
   if(gotFirstOne == false){
       if(number[i] == 1) {
           gotFirstOne = true;
       }
   }
   else {
       number[i] = !number[i];
   }

}

if(number[7] == 0) {
    printf("Overflow occurred");
}

Cheers!!!!




回答5:


My Answer to 2's complement, remember this is for 12 bit complement, you can change mask or integer type as per your requirement. This is working perfectly, also can do it using a Macro.

int twos_compliment(unsigned short a)
{
    int result;
    result = 0x0FFF&a;
    result = (((result&0x800)?(0<<11):(1<<11))|((result&0x400)?(0<<10):(1<<10))
            |((result&0x200)?(0<<9):(1<<9))|((result&0x100)?(0<<8):(1<<8))
            |((result&0x080)?(0<<7):(1<<7))|((result&0x040)?(0<<6):(1<<6))
            |((result&0x020)?(0<<5):(1<<5))|((result&0x010)?(0<<4):(1<<4))
            |((result&0x008)?(0<<3):(1<<3))|((result&0x004)?(0<<2):(1<<2))
            |((result&0x002)?(0<<1):(1<<1))|((result&0x001)?0:1));
    return result=result+1;
}


来源:https://stackoverflow.com/questions/2581410/c-converting-to-2s-complement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!