How to check if two signed 32 bit integers cause overflow in MIPS? - overflow

I have figured out that for two unsigned integers, I can just do this:
sll $a0, $a0, 31 #a0 is integer 1 to be added
sll $a1, $a1, 31 #a1 is integer 2
add $t0, $a0, $a1 #result in $t0
addi $t1, $0, 2
beq $v0, $t0, $t1
What this does is it shifts the 32nd bit of both integers to the first bit spot and it adds them. If both of these numbers are 1, then the answer in $t1 will be 2 (01+01=10). Therefore, an overflow has occurred.
However for signed integers, the leading one signifies negative integers. I've ruled out the possibility for an overflow is both integers are off opposite sign, but suppose they are the same sign. Then 010 + 011 (two positive integers) will give me 101, but because this is signed. This becomes a negative integer. Would I just check if the number has changed signs? And for two negative integers, I can just check as if it were unsigned?

So you are talking about signed overflow? If the carry in does not match the carry out then it is a signed overflow.
abi or
000 00
001 01 signed overflow
010 01
011 10
100 01
101 10
110 10 signed overflow
111 11
a and b are the operands, i is the carry in, o is carry out and r is result.
notice anything about the relationship between a, b, and r? You can determine signed overflow by simply looking at the msbits of the two operands and the result.
This has absolutely nothing to do with mips, it is basic twos complement addition (and subtraction). To apply it to an instruction set you need to isolate the msbits of the operands and if they match the result. Can use a test/and can use, shifting 31 bits assuming it pads with something known (like zero and not sign extends, or maybe sign extension helps). add with zero check the z flag. mips doesnt use flags so and or shift to isolate then compare if equal or not is a good generic solution. can test carry in vs carry out as well (and both operands with 0x7FFFFFFF then add, then shift right 31, and or isolate the carry in and the two operand msbits, then add those three items and see if the carry out is the same or different, takes a lot more instructions).

Related

Shifting bits in MIPS

My professor gave an example to us:
Say your integer is 57412476 which is 0x36C0B7C. If you take out bits
19,20, and 21 and store them in $a0 as the least significant three
bits, you will get 5 in decimal in $a0.
Can someone explain to me how this works? For clarification, if register $a0 contain bits 19,20, and 21 of user input (call it A), the least significant bit of $a0 should contain the 19th bit of A, the second least significant bit of $a0 should contain the 20th bit of A, and so on...

Is this an overflow arithmetic calculation?

So when I read the book and it says that overflow can't occur when add different signs and subtraction of the same sign.
But I have question when I do this: 185 - 122
I converted binary of 122 to 2s complement and did the addition, which is different signs:
185+(-122) and when I add them together, I got the sign bit overflow to 100111111. But if I cut off the MSB on the left, it is the correct answer. Is it an overflow?
No, it isn't overflow - the overflow resulting from the addition of 2 1's in the MSB must just be discarded. From Wikipedia
To get the two's complement of a binary number, the bits are inverted, or "flipped", by using the bitwise NOT operation; the value of 1 is then added to the resulting value, ignoring the overflow which occurs when taking the two's complement of 0.
So in your example
185 10111001
122 01111010 -
Taking the 2's complement of 122 (One's complement +1)
01111010 => 10000110
Adding:
10111001 185
10000110 +(-122)
--------
00111111 (63)
=63
The overflow is ignored.
There are however rules for detecting overflow after doing the 2's complement :
If the sum of two positive numbers results in a negative result
If the sum of two negative numbers results a positive result

Bits confusion on unary complement operator

Bitwise unary complement operator (~) of 2 is -3. I read some where the value 2 in binary representation is 0010 and Bitwise unary complement operator changes bits from 0 to 1, or vice versa. So the value of ~2 is 1101. it means -3. But my confusion is why have they taken 2's binary representation as 0010. according to me int is 32bits. so why 2 cant be 00000000000000000000000000000010 and it's unary complement is 11111111111111111111111111111101? I know am wrong but why? please explain?
The answer to your question is "Two's complement was chosen over one's complement because of several convenient characteristics making arithmetic easier to implement in digital circuits".
I believe from the wording of your question that a bit of an illustration would help.
To fully appreciate this, you still need to read up on two's complement notation and arithmetic - both how they work and their history - but I will try to explain the basics here in a story-like fashion.
Let's say that we have 4 bits in which to represent a signed integer value.
Only 16 distinct values can be represented in 4 bits (16 distinct
different "patterns" can be made with 4-bits)... 0000, 0001, 0010,
0011, 0100, ... 1111 (try it, it's easier to see and develop the
pattern in a columnar format, which you'll see I've done below)
Decide which 16 values you want to be able to represent
It makes sense to say that 0000 stands for zero, 0001 for one, and so on for positives, but what about negatives?
Because zero has "taken one place", we can represent 15 other integers so it is immediately obvious that we cannot represent the same amount of positive and negative values.
We make a choice: our range will run from -8 to +7 (we might have said -9 to +6 or -7 to +8 etc but you'll see below how this choice pays off)
Now which bit-patterns should represent the negatives?
I'm sure you'll agree that it would be very nice if every number added to its additive inverse gave zero without us needing to resort to if-negative-then-else(if positive) logic. E.g. If +3 is represented 0011 and we do (binary) addition of 1101 we get the result (carry 1)0000. Ignore the carry and we've got zero. This makes the bit pattern 1101 obvious winner of the tag "-3".
You can play with the remaining values the same way and what you should arrive at is the following...
-8 1000
-7 1001
-6 1010
-5 1011
-4 1100
-3 1101
-2 1110
-1 1111
0 0000
+1 0001
+2 0010
+3 0011
+4 0100
+5 0101
+6 0110
+7 0111
With the following beautiful and convenient characteristics
"Natural counting bit patterns". Look down the column on the far right and you'll see 0 1 0 1..., then 0 0 1 1... in the next column, then 0 0 0 0 1... etc running perfectly in sequence into the positives
Incrementing "wraps around" (0,1,2,...7,-8,-7,-6,...-1,0,1,...etc and the same goes for decrementing)
Binary addition of additive inverses gives zero with no extra logic to deal with signs
All negative numbers have 1 for their first bit, zero and all positive numbers start with a 0. (The first bit is referred to as "the sign bit".)
Additive inverses can be obtained by the following rule/algorithm: "Invert all bits, increment, discard carry". Magic! Try 3 again:
3 : 0011
~ : 1100 (the NOT operator gives "one's complement")
+1: 1101 (the two's complement representation of -3)
~ : 0010
+1: 0011 (back to +3)
etc
This is two's complement notation
If you've understood this 4-bit story, you'll find that it can be easily extended to apply to 32 bit signed integers.

What is the 2's complement of -17?

What will be the binary value of -17 and how to find the 2's complement of -17?
Assuming an 8-bit word, start with the binary form of 17. = 00010001
Then invert the bits: = 11101110
Then just add 1: = 11101111.
If you've got a 16-, 32- or 64-bit word then you'll have a load more leading 1s.
Even if you do not assume anything, you have to just keep the leftmost bit significant.
Start with the word itself, 10001.
Then invert gives the one's, 01110
Now add 1 to this number. 01111.
But to keep the left most bit significant, append a one there eg,101111
in terms of the minimum number of bits required (6 here).

Is there a bijection between any distinct 4 4-bits strings and all the 2-bits strings?

Let me give you an example, let's consider the strings:
1000
0101
0111
0000
and the full range of 2-bits strings:
00
01
10
11
i am wondering if there is a function that has an inverse and that maps the 4 4-bits string to the 2-bits strings.
The number of bijections from a set of n elements to another set of n elements is n!
Consider each destination element consecutively, and pick its matching origin element.
For the first, you can pick among n.
For the second, you can pick among (n-1).
...
You want a bijection between sets of 4 elements, therefore you have 4! = 24 possible functions.
00 would be mapped to 1000 in six of them (3!), to 0101 in six of them, etc.
I'm not sure this answers your question but that's how I understand it.
For the case of 4 4 bits you have 16 ** 4 or 65536 cases this would map to 8 2 bit cells so it would be a trivial problem. However if you restate your problem to be the bijective mapping of the space of all strings made of 4 bits to 2 bits per byte that is a different problem and yes that has a solution.
A simple solution is look at the mappings to an infinite odd binary string space of each type of pattern. The infinite odd string has a last one a finite distance away from start what you do is you start writing bits as they appear you have one flag if its set and you have done last byte (either the 2 or 4 bit whichever set your using) you write a 1000... if the flag is clear you write 000... since there was a one that is the last "1" in the expansion.
for the 2 bit set
00 sets flag
10 does nothing to flag
the rest 01 11 clear the flag
for the 4 bit set
0000 sets flag
1000 does nothing to flag
rest all contain at least 1 or more ones and clear the flag
converting 1000 0101 0111 0000 to is a straight copy to 100001010111000010000...
notice the tail 100.. since flag set. If you do the reverse for the 2 bit set the
flag goes through many state but the 1000.. at end part of flag so in the
2 bit set you get 10 00 01 01 01 11 00 00 no big deal 8 bytes
but on converting 1000 0101 0111 0100 you get 1000010101110000...
when looking at 2 bit set you get 10 00 01 01 01 11 10
which is one 2 bit unit shorter for 7 bytes
for this bijection from 4 bit set to 2 bit set there will always be either
2n bytes for the byte of two bytes or 2n-1 bytes where n number of 4 bit bytes.
This method of mapping to the infinite odd files works for bijective transform of any string
a member of an infinite set of any number of bytes per byte even if the number of
bits that make up a byte vary a a function of n.

Resources