Objective C Int to 2's Complement Conversion - c

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;

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.

Does signed to unsigned casting in C changes the bit values

I've done some quick tests that a signed int to unsigned int cast in C does not change the bit values (on an online debugger).
What I want to know is whether it is guaranteed by a C standard or just the common (but not 100% sure) behaviour ?
Conversion from signed int to unsigned int does not change the bit representation in two’s-complement C implementations, which are the most common, but will change the bit representation for negative numbers, including possible negative zeroes on one’s complement or sign-and-magnitude systems.
This is because the cast (unsigned int) a is not defined to retain the bits but the result is the positive remainder of dividing a by UINT_MAX + 1 (or as the C standard (C11 6.3.1.3p2) says,
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.
The two’s complement representation for negative numbers is the most commonly used representation for signed numbers exactly because it has this property of negative value n mapping to the same bit pattern as the mathematical value n + UINT_MAX + 1 – it makes it possible to use the same machine instruction for signed and unsigned addition, and the negative numbers will work because of wraparound.
Casting from a signed to an unsigned integer is required to generate the correct arithmetic result (the same number), modulo the size of the unsigned integer, so to speak. That is, after
int i = anything;
unsigned int u = (unsigned int)i;
and on a machine with 32-bit ints, the requirement is that u is equal to i, modulo 232.
(We could also try to say that u receives the value i % 0x100000000, except it turns out that's not quite right, because the C rules say that when you divide a negative integer by a positive integer, you get a quotient rounded towards 0 and a negative remainder, which isn't the kind of modulus we want here.)
If i is 0 or positive, it's not hard to see that u will have the same bit pattern.
If i is negative, and if you're on a 2's complement machine, it turns out the result is also guaranteed to have the same bit pattern. (I'd love to present a nice proof of that result here, but I don't have time just now to try to construct it.)
The vast majority of today's machines use 2's complement. But if you were on a 1's complement or sign/magnitude machine, I'm pretty sure the bit patterns would not always be the same.
So, bottom line, the sameness of the bit patterns is not guaranteed by the C Standard, but arises due to a combination of the C Standard's requirements, and the particulars of 2's complement arithmetic.

Twos Complement ~0 signed

I'm new here but I was just wondering what ~0 would be if in the two's complement system, signed integer.
Is it -1 because the flipping of 0 is 1, but if it's signed the answer would be -1? Or is the answer just 1 and just because I'm working with signed numbers doesn't mean that it would be -1?
0 is a signed int (if you wanted it to be unsigned, you'd write 0U) and therefore ~0 is also a signed int.
If your machine uses a 2's-complement representation, then that will have the value -1. The vast majority of machines -- possibly all the machines you will ever see in your career -- are 2's-complement, but technically speaking, ~0 may invoke undefined behaviour if you use it on a machine which uses 1's-complement representation of signed integers and which also prohibits negative zeros.
Even if it may not matter, it's a good idea to get into the habit of only using unsigned integer types with bitwise operators.
Remember that the bitwise operators perform "the integer promotions" on their operands, which means that signed and unsigned short and char are automatically promoted to int -- not unsigned int (unless it happens that short is the same width as int) -- so an explicit cast to unsigned may be necessary.
~0 is not the two's complement of zero. It is the bit inversion of 0, which is the same as the one's complement.
If you want the two's complement in C, you will need -0 (note the minus sign)
And, -0 would just be 0.
Proof (in eight bit)
zero - 0b00000000
one'e complement - 0b11111111
Add one - 0b00000001 (ignoring overflow)
-----------
Two's complement - 0b00000000

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
------------------------

Overflow in bitwise subtraction using two's complement

When performing bitwise subtraction using two's complement, how does one know when the overflow should be ignored? Several websites I read stated that the overflow is simply ignored, but that does not always work -- the overflow is necessary for problems like -35 - 37, as an extra digit is needed to express the answer of -72.
EDIT: Here's an example, using the above equation.
35 to binary -> 100011, find two's complement to make it negative: 011101
37 to binary -> 100101, find two's complement to make it negative: 011011
Perform addition of above terms (binary equivalent of -35 - 37):
011101
011011
------
111000
Take two's complement to convert back to positive: 001000
The above is what many websites (including academic ones) say the answer should be, as you ignore overflow. This is clearly incorrect, however.
An overflow happens when the result cannot be represented in the target data type. The value -72 can be represented in a char, which is a signed 8-bit quantity... there is no overflow in your example. Perhaps you are thinking about a borrow while doing bitwise subtraction... when you subtract a '1' from a '0' you need to borrow from the next higher order bit position. You cannot ignore borrows when doing subtraction.
-35 decimal is 11011101 in two's complement 8-bit
+37 decimal is 00100101 in two's complement 8-bit
going right to left from least significant to most significant bit you can subtract each bit in +37 from each bit in -35 until you get to bit 5 (counting starts at bit 0 on the right). At bit position 5 you need to subtract '1' from '0' so you need to borrow from bit position 6 (the next higher order bit) in -35, which happens to be a '1' prior to the borrow. The result looks like this
-35 decimal is 11011101 in two's complement 8-bit
+37 decimal is 00100101 in two's complement 8-bit
--------
-72 decimal is 10111000 in two's complement 8-bit
The result is negative, and your result in 8-bit two's complement has the high order bit set (bit 7)... which is negative, so there is no overflow.
Update:I think I see where the confusion is, and I claim that the answer here Adding and subtracting two's complement is wrong when it says you can discard the carry (indicates overflow). In that answer they do subtraction by converting the second operand to negative using two's complement and then adding. That's fine - but a carry doesn't represent overflow in that case. If you add two positive numbers in N bits (numbered 0 to N-1) and you consider this unsigned arithmetic range 0 to (2^N)-1 and you get a carry out of bit position N-1 then you have overflow - the sum of two positive numbers (interpreted as unsigned to maximize the range of representable positive numbers) should not generate a carry out of the highest order bit (bit N-1). So when adding two positive numbers you identify overflow by saying
there must be no carry out of bit N-1 when you interpret them as unsigned and
the result in bit N-1 must be zero when interpreted as signed (two's complement)
Note, however, that processors don't distinguish between signed and unsigned addition/subtraction... they set the overflow flag to indicate that if you are interpreting your data as signed then the result could not be represented (is wrong).
Here is a very detailed explanation of carry and overflow flag. The takeaway from that article is this
In unsigned arithmetic, watch the carry flag to detect errors.
In unsigned arithmetic, the overflow flag tells you nothing interesting.
In signed arithmetic, watch the overflow flag to detect errors.
In signed arithmetic, the carry flag tells you nothing interesting.
This is consistent with the definition of arithmetic overflow in Wikipedia which says
Most computers distinguish between two kinds of overflow conditions. A carry occurs when the result of an addition or subtraction, considering the operands and result as unsigned numbers, does not fit in the result. Therefore, it is useful to check the carry flag after adding or subtracting numbers that are interpreted as unsigned values. An overflow proper occurs when the result does not have the sign that one would predict from the signs of the operands (e.g. a negative result when adding two positive numbers). Therefore, it is useful to check the overflow flag after adding or subtracting numbers that are represented in two's complement form (i.e. they are considered signed numbers).

Resources