I am having a hardtime understanding the borrowing logic for 1000 - 0110 . I know the answer would be 0010 but I am having trouble understanding the borrowing part a little.
First Step is Ok 0 - 0 = 0
1000
0110
----
0
Second Step 0 - 1 , so we need to borrow . We borrow 1 and as result 10 - 1 = 1
->1
1000
0110
----
10
But at the next step there is nothing to borrow, so how does it work ?
When you borrow, you carry over binary 10 to the lower bit, so:
0
->1
0000
0110
----
0
Then you borrow again, and subtract 1 from 10, which is 1:
0
->11
0000
0110
----
0
And finally:
0
->11
0000
0110
----
0010
In computer, number will be presented as 2 parts: sign bit and value bits. a - b will be performed as a + (-b)
for positive number, its sign part is 0, value part is its binary representation. For your case, it's: 0 1000
for negative number, its sign part is 1, value part is: ~number + 1, for 0110, ~a is 1001, +1, the representation is : 1 1010
0 1000
1 1010
=======
0 0010
it is positive number 2
Related
Let's take the number 28 in binary:
0b11100 # 28
If we subtract 1 from the number it looks like this:
0b11011 # 27
How I would explain how it 'looks' is that when subtracting 1 from a number, the right-most 1-bit is set to zero and all zeros after it are set to one. For example:
0b10101 - 1
= 0b10100
0b01000 - 1
= 0b00111
0b10000000 - 1
= 0b01111111
What would be the best explanation as to why this occurs though? I'm sure it's a property of binary twos complement, but I'm trying to figure out the best way to explain this to myself so that I can gain a deeper understanding of it.
Binary numbers have general form of N = dn x b^n + dn-1 x b^n-1… d1 x b^1 + d0 x b^0 where b is a base (2), d is a digit < base (0, 1) and n is position.
We write down binary numbers without b (because we know that's always 2) and also without its n exponent which goes implicitly from 0 for least significant digit (rightmost), 1 next to rightmost, etc.
For example your number 28 is 1x 2^4 + 1x 2^3 + 1x 2^2 + 0x 2^1 + 0x 2^0 = 1x 16 + 1x 8 + 1x 4 + 0x 2 + 0x 1 .
In binary:
1 - 1 = 0
0 - 1 = 1 and you carry that - 1 to the next position on left (same as when you do 10 - 1 in decimal, 0 - 1 is 9 and carry - 1 to order of tenths)
When subtracting 1 you go from the rightmost position, if there's 0 you turn it to 1 and carry subtraction up to next (left) position (and that chains all the way left until you find position where you can subtract without affecting higher position)
0b01000 - 1 can be written as 0x 2^4 + 1x 2^3 + 0x 2^2 + 0x 2^1 + 0x 2^0 - 1 x 2^0. In plain decimal that is 8 - 1 = 7 and 7 in binary is 0x 2^4 + 0x 2^3 + 1x 2^2 + 1x 2^1 + 1x 2^0 (4 + 2 + 1)
It does not matter what base you are in, the math does not change:
1000
- 0001
========
This is base 10, easier to see:
1 0 0 0
- 0 0 0 1
=============
We start in the ones column (base to the power 0), the top number is smaller than the bottom so we have to borrow, but what we find is that next column does not have anything and so on so we have to work over until we can borrow something, that value is base larger than the column it is in so if you borrow from the hundreds column into the tens column that is 10 tens so:
So first borrow:
0 10 0 0
- 0 0 0 1
=============
Second borrow:
0 9 10 0
- 0 0 0 1
=============
Third borrow:
0 9 9 10
- 0 0 0 1
=============
And now we can work the base to the power one column:
0 9 9 10
- 0 0 0 1
=============
9
And in this case can easily finish it up:
0 9 9 10
- 0 0 0 1
=============
0 9 9 9
So base 5:
1 0 0 0
- 0 0 0 1
===================
0 5 0 0
- 0 0 0 1
===================
0 4 5 0
- 0 0 0 1
===================
0 4 4 5
- 0 0 0 1
===================
0 4 4 5
- 0 0 0 1
===================
0 4 4 4
And base 2:
1 0 0 0
- 0 0 0 0
==============
0 10 0 0
- 0 0 0 0
==============
0 1 10 0
- 0 0 0 0
==============
0 1 1 10
- 0 0 0 0
==============
0 1 1 10
- 0 0 0 0
==============
0 1 1 1
Twos complement comes into play when you actually implement this in logic, we know from elementary programming classes that when we talk about "twos complement" we learn to "invert and add one" to negate a number. And we know from grade school math that x - y = x + (-y) so:
0
1000
- 0001
=======
This is the same as:
1 <--- add one
1000
+ 1110 <--- invert
=======
Finish:
10001
1000
+ 1110
=======
0111
So for subtraction you invert/ones complement the second operand and the carry in and feed these to an adder. Some architectures invert the carry out and call it a borrow, some just leave it unmodified. When doing it this way as we see above the carry out is a 1 if there was NO borrow. It is a zero if there was a borrow.
I believe this is a base 2 thing only due to having only zero or one. How do you invert a base 10 number? 1000 - 1 = 1000 + 9998 + 1, hmm actually that works.
So base 10 100 - 1 = 99, base 9 100 - 1 = 88, base 8 (octal) 100 - 1 = 77, base 7 100 - 1 = 66 and so on.
I'm trying to adapt a program that counts the occurrences of a char in a file to store a list of the hex addresses where the matches occurred in a far-off memory location. Code:
011 0000 0000 0000 ;Codes x3000 as Load-address of program
0101 010 010 1 00000 ;R2 <- 0
0010 011 000010000 ;R3 <- M[x3012]
1111 0000 0010 0011 ;TRAP x23 (Loads INPUT into R0)
0110 001 011 000000 ;R1 <- M[R3]
;LOOP BEGINS HERE
0001 100 001 1 11100 ;R4 <- R1 - EOT
0000 010 000001000 ;If above = 0, exit loop
1001 001 001 111111 ;R1 <- NOT R1
0001 001 001 1 00001 ;R1 <- R1 + 1
0001 001 001 0 00 000 ;R1 <- R1 + R0
0000 101 000000001 ;If above != 0, do NOT increment counter
0001 010 010 1 00001 ;R2 <- R2 + 1 (increment counter)
0001 011 011 1 00001 ;R3 <- R3 + 1 (increments pointer to next char in file)
0110 001 011 000000 ;R1 <- M[R3] (loads next char into R1)
0000 111 111110110 ;BRnzp x3004 (unconditionally RETURN to loop start)
;LOOP ENDS HERE
0010 000 000000100 ;R0 <- M[x3013]
0001 000 000 0 00 010 ;R0 <- R0 + R2
1111 0000 0010 0001 ;TRAP x21 (OUTPUT)
1111 0000 0010 0101 ;TRAP x25 (HALT)
0011 0001 0000 0000 ;Codes x3100 for the starting address of the file
0000 000 000110000 ;ASCII template
So my program starts at memory address x3000. I want to begin the set of instructions that will handle the list at x300B (below the "increment R2" instruction). Trouble is, I want to start the list at x3500, and I don't know of an "efficient" way to get there.
My original plan was to use a Load Indirect (LDI) instruction, but because of sign-extension, the 9-bit offset only allows an offset of at most x00FF = 0000 0000 1111 1111, which only takes me from x300C (x300B with program counter incremented) to x310B.
The only real "workaround" I've come up with is to use a Load Effective Address (LEA) instructions to store the address x310B in a register (say R5), then store the value x00FF in R6, and repeatedly add R6 to R5 until I get to x3408 (that would take 3 ADD instructions), at which point I'd store the value x0092 in R6, add that to R5, and I'd FINALLY have x3500 in R5.
At that point, the rest is trivial (store R3 in (R5 + counter), which would put the address of the current match into the appropriate "spot" on the list)
I haven't actually done this yet because the whole method of getting to x3500 I described above seems really cumbersome and clumsy. I can't shake the feeling that there has to be a better, faster way to move that many memory addresses at the same time.
Is it possible to move from x300C to x3500 in a single instruction? Even two would be better than what I've currently got.
You wouldn't want to do that, it is possible but a simpler method would be to use LD (opcode 0010) and LDR (opcode 0110) to do this. No need to have the PC jump to x3500 (which would start executing the data in your array which is bad)
Have an address contain the bits 0011 0101 0000 0000
Opcode 0010 will allow you to pull the x3500 into a register. Opcode 0110 will then allow you to load values from your array.
My book says that to get the two's-complement representation, to just flip the bits and add 1. Correct me if I am wrong but the binary representation of -1 would be:
1000 0001
The MSB 1 denotes the sign (1 being negative number) and the 1 at the very end is where the 1 comes from.
So when I flip the bits:
0111 1110
So why does my book say that the two's complement representation of -1 is 1111 1111? I assume I am messing up somewhere.
The book has right. 1111 1111 is the representation of -1 in two's complement.
Try add one to 1111 1111. The result is:
1111 1111 +
0000 0001
---------
1 0000 0000
The "one" at the beginning of the result is the "carry bit". The result is your answer: 0.
At first glance you would say that overflow has occurred, but not at this time, because the result (the zero) can be represented on 8 bits.
One more example:
If you add -1 to -1 then you should get -2:
1111 1111 +
1111 1111
---------
1 1111 1110
And so on...
So why does my book say that the two's complement representation of -1 is 1111 1111?
It's because the MSB is negative and the rest is positive:
1111 1111 = -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 => -1
If you flip the bits of 1111 1111 you would get 0000 0000 if you add one then its 0000 0001 = 1 but that would be -1. Conversely if you want to represent -1 then think of it in reverse. 1 is represented 0000 0001 subtract 1 => 0000 0000, then flip it => 1111 1111. And -2 from above. 2 => 0000 0010. Subtract 1 => 0000 0001, flip it => 1111 1110.
I have this project listen below and im not sure where to start maybe someone can give me a few pointers or perhaps point me in the right direction of starting this?
Thanks!!
Input: A, B = octal digits (see representation below); Cin = binary digit
Output: S = octal digit (see representation below); Cout = binary digit
Task: Using binary FAs, design a circuit that acts as an octal FA. More specifically,
this circuit would input the two octal digits A, B, convert them into binary numbers, add
them using only binary FAs, convert the binary result back to octal, and output the sum as
an octal digit, and the binary carry out.
Input/Output binary representation of octal digits
Every octal digit will be represented using the following 8-bit binary representation:
Octal 8-bit Input Lines:
Digit: 0 1 2 3 4 5 6 7
0 1 0 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0
2 0 0 1 0 0 0 0 0
3 0 0 0 1 0 0 0 0
4 0 0 0 0 1 0 0 0
5 0 0 0 0 0 1 0 0
6 0 0 0 0 0 0 1 0
7 0 0 0 0 0 0 0 1
You are required to design the circuit in a structured way.
Ok, so essentially you're being asked to design a 8-to-3 encoder and a 3-to-8 decoder. Because you're given FAs to work with that's not the point of the assignment.
First we need to define how an encoder and decoder function. So we construct a truth table:
Encoder:
Input | Output
01234567 | 421
-----------------
10000000 | 000
01000000 | 001
00100000 | 010
00010000 | 011
00001000 | 100
00000100 | 101
00000010 | 110
00000001 | 111
and the decoder is just the reverse of that.
Next, how do we construct our encoder? Well, we can simply attack it one bit at a time.
So for the 1s digit we have if input bit 1, 3, 5 or 7 is set then it's 1, otherwise it's 0. So we just need a giant OR with 4 inputs connected to 1, 3, 5 and 7.
For the 2s digit we need the OR gate connected to 2, 3, 6, 7. Finally for the 4s gate, connect them to 4, 5, 6, 7. This doesn't do any error checking to make sure extra bits aren't set. Though, the behavior in that case seems to be undefined by spec, so it's probably OK.
Then you take your three lines and feed them to your adders. This is easy so I won't get into it.
Finally you need a decoder, this is a bit more tricky than the encoder.
Let's look at the decoder truth table:
Input | Output
421 | 01234567
----------------
000 | 10000000
001 | 01000000
010 | 00100000
011 | 00010000
100 | 00001000
101 | 00000100
110 | 00000010
111 | 00000001
This time we can't just use 3 or gates and call it a day.
Let's write this down in C-like code:
if (!input[0] && !input[1] && !input[2])
output[0] = 1
if (input[0] && !input[1] && !input[2])
output[1] = 1
if (!input[0] && input[1] && !input[2])
output[2] = 1
if (input[0] && input[1] && !input[2])
output[3] = 1
if (!input[0] && !input[1] && input[2])
output[4] = 1
if (input[0] && !input[1] && input[2])
output[5] = 1
if (!input[0] && input[1] && input[2])
output[6] = 1
if (input[0] && input[1] && input[2])
output[7] = 1
So, it looks like we're going to be using 8 3 input AND gates, and three NOT gates!
This one is a bit more complicated, so I made an example implementation:
If the conversion is to be done by hand in class, you can try the following way.
Conversion of Octal to Binary:
To convert octal to binary, replace each octal digit by its binary representation.
Example: Convert 518 to binary:
58 = 1012
18 = 0012
Therefore, 518 = 101 0012.
Conversion of Binary to Octal:
The process is the reverse of the previous algorithm. The binary digits are grouped by threes, starting from the decimal point(if present) or the last digit and proceeding to the left and to the right. Add leading 0s (or trailing zeros to the right of decimal point) to fill out the last group of three if necessary. Then replace each trio with the equivalent octal digit.
Example, convert binary 1010111100 to octal:
(Adding two leading zero's, the number is 001010111100)
001 = 1, 010 = 2, 111 = 7, 100 = 4
Therefore, 1010111100 = 1274
To convert to and from octal you can use an encoder & decoder pair (http://www.asic-world.com/digital/combo3.html). The 3 bit adder can be made from chaining the 3 FAs.
I am using bloom filters to check for duplicated data in a set. However, there is a need to combine the results of two sets of data into a single filter to check for duplication across the two sets. I devised a function in pseudo-Python to perform this task:
def combine(a : bloom_filter, b : bloom_filter):
assert a.length == b.length
assert a.hashes == b.hashes
c = new bloom_filter(length = a.length, hashes = b.hashes)
c.attempts = a.attempts + b.attempts
c.bits = a.bits | b.bits
# Determining the amount of items
a_and_b = count(a & b)
a_not_b = count(a & !b)
not_a_b = count(!a & b)
neither = count(!a & !b)
c.item_count = a_not_b / a.length * a.item_count
+ not_a_b / b.length * b.item_count
+ a_and_b / c.length * min(a.item_count, b.item_count)
return c
Does this even sound correct? I am having considerable internal debate as to whether is is even possible to do what I intend, since much of the information about the source data is lost (which is the point of a bloom filter).
You can derive a formula for estimating the amount of items a Bloom Filter:
c = log(z / N) / ((h * log(1 - 1 / N))
N: Number of bits in the bit vector
h: Number of hashes
z: Number of zero bits in the bit vector
This provides a fairly accurate estimate of the number of items in the Bloom Filter. You can come up with an estimate for contribution with simple subtraction.
It could be possible..... sort of..
lets say set A contains apples and oranges
lets say set B contains peas and carrots
construct a simple 16 bit bloom filter as an example and CRC32 as the hash
crc32(apples) = 0x70CCB02F
crc32(oranges) = 0x45CDF3B4
crc32(peas) = 0xB18D0C2B
crc32(carrots) = 0x676A9E28
Start w/ empty bloom filter (BF) (say 16 bits) for both sets (A, B)
BFA = BFB = 0000 0000 0000 0000
then, breaking the hash into some bit length, we'll use 4 here
we can add apples to the BF.
e.g.
Get Apples BF Index list by splitting up the hash:
0x70CCB02F = 0111 0000 1100 1100 1011 0000 0010 1111
7 0 C C B 0 2 F
----------------------------------------------------
Add Apples to BFA by setting BF bit indexes [ 7, 0, 12, 12, 11, 0, 2, 15]
(set the index bit of an empty BF to 1)
Apples = 1001 1000 1000 0101 (<- see indexes 0,2,7,11,12,15 are set)
BF = 0000 0000 0000 0000 (or operation adds that item to the BF)
================================
Updated BFA = 1001 1000 1000 0101
Add Oranges to BF same way:
0x45CDF3B4 = 0100 0101 1100 1101 1111 0011 1011 0100
4 5 12 13 15 3 11 4
----------------------------------------------------
Add oranges to BF by setting BF bit indexes [ 4,5,12,13,15,3,11,4]
Oranges = 1011 1000 0011 1000
BFA = 1001 1000 1000 0101 (or operation)
================================
Updated BFA = 1011 1000 1011 1101
So now apples and oranges are inserted into BF1
w/ Final Value of 1011 1000 1011 1101
Do the same for BFB
crc32(peas) = 0xB18D0C2B becomes =>
set [11,2,12,0,13,1,8] in BFB
0011 1001 0000 0011 = BF(peas)
crc32(carrots) = 0x676A9E28 becomes =>
set [8,2,14,9,10,6,7] in BFB
0100 0111 1100 0100 = BF(carrots)
so BFB =
0011 1001 0000 0011 BF(peas)
0100 0111 1100 0100 BF(carrots)
=================== ('add' them to BFB via locial or op)
0111 1111 1100 0111
you could now search B for A entries in a loop and vice verse:
Does B contain "oranges" =>
1011 1000 0011 1000 (Oranges BF representation)
0111 1111 1100 0111 (BFB)
===================== (and operation)
0011 1000 0000 0000
Because this result (0011 1000 0000 0000) doesn't match the
Original BF of Oranges, you can be certain that B doesn't contain any oranges
... ... (do for rest of items)
and following, B doesn't contain any of A items,
just as B doesn't contain any of the apples.
I don't think that's what you asked though, and looks like you could computer a difference
BF, which is more to your point. Seems like you could do a xor op and that would give you a 'single' array containing both differences:
0111 1111 1100 0111 (BFB)
1011 1000 1011 1101 (BFA)
========================
1100 0111 0111 1010 (BFA xor BFB) == (items in B not in A, and items in A not in B)
meaning with this single BF, you could detect the non-existance of an item 100% of the time,
just not the existance of the item 100%.
The way you would use it, is as follows (check if peas is 'missing from A):
1100 0111 0111 1010 (BFA xor BFB)
0011 1001 0000 0011 (Peas)
============================== (And operation)
0000 0001 0000 0010 (non-zero)
since (BFA xor BFB) && (Peas) != 0 you know one set does not contain 'peas'...
again, you'd be testing for item by item, maybe you could do aggregation but probably not a good idea...
Hope this helps!