How to get two's complement of an int in C? [duplicate] - c

This question already has answers here:
Display the binary representation of a number in C? [duplicate]
(8 answers)
Closed 6 years ago.
How do you get the Two's complement for a int in C?
Say for example I had an int such as -254, how would I go about converting this to 100000010?
Is there any way to pull out the Two's complement value from the integer variable, as I know that in C, the ints are stored in Two's comp?

If you're operating on unsigned ints then you can invert the bits ~ and add 1 to yield the 2s complement value. x=(~y)+1; If your machine uses a 2s complement representation for signed int then this should convert (by the implementation's definition) to the proper signed int value.
The C language itself is a little vague in its guarantees in this area. To work portably on the bitwise representation of an object you should use an unsigned type.

know that in C, the ints are stored in Two's comp
Not guaranteed, but in practice every computer uses two's complement.
Is there any way to pull out the Two's complement value from the integer variable
It is already in two's complement format, so it is unclear what you are asking. It would seem you are asking how to print a variable in binary format?
int data = -254;
const size_t BITS = 8*sizeof(data);
char bin_str[BITS+1];
for(unsigned int i=0; i<BITS; i++)
{
unsigned int mask = 1u << (BITS - 1 - i);
bin_str[i] = (data & mask) ? '1' : '0';
}
bin_str[BITS] = '\0';

You can convert signed-magnitude to two's complement by subtracting the number from 0x80000000 if the number is negative. This will work for a 32-bit integer on a machine using two's complement to represent negative values, but if the value is positive this will result in a two's complement negation. A right shift of a two's complement negative number will shift in one's, we can utilize this to make a mask to select between the original value, or the conversion of a signed-magnitude negative value to a two's complement negative value.
int sm2tc(int x) {
int m = x >> 31;
return (~m & x) | (((x & 0x80000000) - x) & m);
}
Original Code posted by Apriori

Actually, there is an easy way to do this. Simply convert your number to a binary string, and convert that string back to an integer.
Use itoa, which converts a number to its given base in string form.
http://www.cplusplus.com/reference/cstdlib/itoa/
Then, simply use the familiar atoi that converts it back to an int.

Related

FInd Two's Complement for Unsigned Integer

I have a simple function that will find the two's Complement for an unsigned integer and then test it to make sure that it is correct
unsigned twoscomplement(unsigned v) {
};
int main()
{
unsigned a = 255;
unsigned c = twoscomplement(a);
unsigned s = a+c;
printf("%u+%u=%u\n", a, c, s);
return 0;
}
When I asked about how I would go around solving this I got the answer unsigned c = (~a)+1; From what I understood (~a) flips the bits and then +1 is for the overflow? Any help on this matter would be appreciated
Whenever we work with one’s complement or two’s complement, we need to state what the word size is. If there are w bits in the word, then the one’s complement of a number x is obtained by subtracting x from the binary numeral made of w 1s. If w is 16, we use 11111111111111112, which is 65535. Then the one’s complement of x is 11111111111111112−x. Viewing x as a binary numeral (with at most w bits), whatever bits are on in x will be off in 11111111111111112−x, and whatever bits are off in x will be on in 11111111111111112−x. Hence, all the bits are complemented.
C has an operator for the one’s complement; ~x flips all the bits, so it produces the one’s complement of x.
The two’s complement of x is 2w−x, by definition (except that the two’s complement of 0 is 0). 2w equals one plus that binary numeral made of w 1s. For example, 216 = 65535 + 1. Therefore, the two’s complement is one more than the one’s complement. Therefore the two’s complement of x is ~x + 1.
C also has an operator for the two’s complement, for unsigned integers. Unsigned arithmetic is defined to “wrap” modulo 2w; whenever a regular arithmetic result is outside that range, it is brought back into that range by adding or subtracting 2w as needed. The regular arithmetic negation of x would be negative (if x is not zero), so the computed result of -x is −x + 2w = 2w−x, which is the two’s complement of x.

Objective C Int to 2's Complement Conversion

I'm trying to convert my 16 bit integer to two's complement if it's negative.
At the moment, I'm using the One's complement operator. I figure I can use that, and then add 1 to the binary value to convert it to two's complement. However, I'm unable to do x = ~a + 1 because that just yields the integer value + 1.
If my process is correct, how can I add 1 to the binary integer? If not, what is the most appropriate way to convert a 16 bit integer to 2's complement in Objective-C?
A two's complement is a kind of representation of signed numbers, not a value or an operation. On nearly all modern computers two's complements are the standard representation of signed integers. (And it is one of three allowed representations of integers in the standard.)
Therefore if you have any signed integral number, it is represented in two's complement. I think you want to have "the" two's complement of a positive number. This is simply the negative value, if your machine uses two's complements for signed numbers.
int positiveValue = 5;
int twosComplement = -positiveValue;

Calculating 2's compliment of a number [duplicate]

This question already has answers here:
How to take twos complement of a byte in c++?
(4 answers)
Closed 6 years ago.
I was working on converting 60 to 2's complement. This is how I did:
60 to binary 00111100
1's compliment 11000011
2's compliment 11000100 (by adding 1 to the 1's compliment)
When I execute this in a program using the following piece of code
#define NUM 60
unsigned char c;
c=~NUM;
printf("%d",c);
it prints 195 not 196. Please explain the reason behind this? Also explain process of calculating (~) of any given number.
The expression ~NUM is not strictly portable. To calculate your ones complement, you could try subtracting from UCHAR_MAX instead, for example: c = UCHAR_MAX - NUM;. This will work portably because according to the standard, UCHAR_MAX is required to be a binary power minus one:
The value UCHAR_MAX shall equal 2CHAR_BIT - 1.
Don't forget to increment c afterwards, as in your final step on paper: c++.
You could safely perform the entire twos complement operation in one step, providing your underlying choice of representation is unsigned (which it should be, because the whole idea of twos complement is to represent signed integers on an unsigned group of bits): c = -NUM;. This is because negative numbers are converted to unsigned types using the following procedure also described within the C11 standard:
... if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.
In this case that repeatedly happens to be once: -60 + UCHAR_MAX + 1 == 196 when UCHAR_MAX == 255. If we were talking about a larger value, such as -32767 then multiple such additions would be required.
On that note, if you need to operate with numbers greater than 32768 for NUM, you'll want to think about different suffixes, for example #define NUM 32768L would be sufficient, and much larger than that #define NUM 2147483648LL.
The operator ~ performs a logical not giving back the 1's complement, not the 2's complement.
To perform the 2's complement in C use the - unary minus. See the following example:
#define NUM 60
char c1 = ~NUM; //1's complement
char c2 = -NUM; //2's complement
printf("NUM=%d, 1's complement=%d, 2's complement=%d\n",NUM, c1, c2);
But the main point is that you cannot perform a 2's complement on an unsigned type, because by default the 2's complement is used to find the representation of the same negative number. I.e. 2 -2, 10 -10, 5 -5, etc.
Consider that the values you are looking for are the unsigned representation of the negative (2's complement) value. I.e. adding:
printf("2's complementunsigned representation=%d\n", (unsigned char)c2);
Will print 196, that is -60, read as an unsigned value.
The symbol ~ calculates the 1's complement of the number. You just have to add 1 to the calculation.
c = ~NUM + 1;
Your description of the process of calculating the 1's complement is correct. To know more about it visit the wiki page on 1's complement.
Cheers!
The ~ gives you the one's complement. Use negate (-) to get the two's complement.
#include <stdio.h>
#define NUM0 0
#define NUM60 60
int main() {
unsigned char b;
unsigned char c;
b = ~NUM0;
c = -NUM0;
printf( "b=%d c=%d", b, c );
b = ~NUM60;
c = -NUM60;
printf( "b=%d c=%d", b, c );
}
outputs:
b=255 c=0
b=195 c=196

Using bit mask to convert a signed integer into two's complement

I am given this code to convert a signed integer into two's complement but I don't understand how it really works, especially if the input is negative.
void convertB2T( int32_t num) {
uint8_t bInt[32];
int32_t mask = 0x01;
for (int position = 0; position < NUM_BITS; position++) {
bInt[position] = ( num & Mask) ? 1 : 0;
Mask = Mask << 1;
}
}
So my questions are:
num is an integer, Mask is a hex, so how does num & Mask work? Does C just convert num to binary representation and do the bitwise and? Also the output of Mask is an integer correct? So if this output is non-zero, it is treated as TRUE and if zero, FALSE, right?
How does this work if num is negative? I tried running the code and actually did not get a correct answer (all higher level bits are 1's).
This program basically extracts each bit of the number and puts it in a vector. So every bit becomes a vector element. It has nothing to do with two's complement conversion (although the resulting bit-vector will be in two's complement, as the internal representation of numbers is in two's complement).
The computer has no idea what hex means. Every value is stored in binary, because binary is the only thing computer understands. So, ,the "integer" and the hex values are converted to binary (the hex there is also an integer). On these binary representations that the computer uses, the binary operators are applied.
In order to understand what is happening with the result when num is negative, you need to understand that the result is basically the two's complement representation of num and you need to know how the two's complement representation works. Wikipedia is a good starting point.
To answer your questions
1.Yes num is integer represented in decimal format and mask is also integer represented in hex format.
Yes C compiler treats num and mask with their binary equivalents.
Say
num = 24; // binary value on 32 bit machine is 000000000000000000011000
mask = 0x01; // binary value on 32 bit machine is 000000000000000000000001
Yes compiler now performs & bitwise and the equivalent binary values.
Yes if output is nonzero, treated as true
If a number is negative, its represented in 2's complement form.
Basically your code is just storing binary equivalent of number into array. You are not representing in twos complement.
If MSB is 1 indicates number is negative. if a number is negative
num = -24; // represent binary value of 24
000000000000000000011000 -> apply 1's complement + 1 to this binary value
111111111111111111100111 -> 1's complement
+000000000000000000000001 -> add 1
------------------------
111111111111111111101000 -> -24 representation
------------------------

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?
i.e. 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 x.u 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.
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.
By applying bitwise operations. E.g. 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 (e.g. 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.
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

Resources