In a computer why does adding one to the maximum integer results in zero? - binary

I wonder the process of addition in computers.
How do computers add two number? Is it an electronic magic? Is it an algorithm?
Also, I wonder why adding 1 to Max integer (...111) results in zero (...000)? Asuming ...111 is the binary representation of max int in that computer architecture.
Thank you.

It doesn't always result in 0. If you're using a signed integer type in the most representation, you'll end up with the minimum value, going from (say)
01111111 (127)
10000000 (-127)
On some architectures - and in some modes, at least - this sort of overflow doesn't give a value, it causes an error. When it does give a value, it's basically still just binary counting. Imagine you have an 8-bit unsigned integer value... the last few values would be
11111100
11111101
11111110
11111111
then the logical next step is to go into the next bit:
100000000
So the computer effectively does that - but then throws away that new top bit, keeping just the bottom 8 bits (because it's an 8-bit type).
You don't have to use computers to see this sort of effect though. Suppose you have an analogue odometer in a car - the kind with several "wheels". As you get to the end of its range, it just wraps round:
99997
99998
99999
00000 // Overflow!

This is the case in an arithmetic processor which implements two's complement binary arithmetic for integers. It is not true of, say, floating point numbers and it's not necessarily true on rare computers that do math in other ways (sign-magnitude representations, etc).
two's complement makes certain things easy for the hardware, like implementing some signed and unsigned operations using the same logic.
Remember, the value 1111...1111 represents -1 under two's complement, and you want -1 to increment to 0.
1111111..111 goes to zero "naturally". When you add 1, a carry of 1 propagates through the number, causing every digit to turn to 0, and then it carries out of the number (where it is discarded, or used to set an overflow indication).

The process of addition is hardware related and done ALU in your CPU .
Adding 1 to Max integer will cause in zero
Because in binary system adding 1 to 1 will result in zero and 1 added to the next digit
So the adding 1 to 11111
1+1=0 and 1 shifted to the next digit and so on

How do computers add two number? Is it an electronic magic? Is it an algorithm?
Computers use an algorithm called 2's complement to represent positive and negative numbers (signed numbers).
Following is the explanation of Sign Bit, 1's complement and 2's complement.
Let's take a 4 bit integer
Sign Bit
| Binary | Decimal |
| :-----: | :-----: |
| 1 1 1 1 | -7 |
| 1 1 1 0 | -6 |
| 1 1 0 1 | -5 |
| 1 1 0 0 | -4 |
| 1 0 1 1 | -3 |
| 1 0 1 0 | -2 |
| 1 0 0 1 | -1 |
| 1 0 0 0 | -0 |
| 0 0 0 0 | +0 |
| 0 0 0 1 | +1 |
| 0 0 1 0 | +2 |
| 0 0 1 1 | +3 |
| 0 1 0 0 | +4 |
| 0 1 0 1 | +5 |
| 0 1 1 0 | +6 |
| 0 1 1 1 | +7 |
As you can see from the above truth table, the difference between +5 and -5 is just the left most bit, i.e., the Most Significant Bit.
The MSB is used to determine the sign of the number. Hence, the name.
There are a few problems with this approach,
There's a +0 and a -0.
If you add 2 numbers. For e.g., +5 and -5 you should get 0 but when adding 0 1 0 1 with 1 1 0 1 you get 1 0 0 1 0, we're using 4 bit integer, so we can ignore the first 1. So, we get 0 0 1 0 which is 2.
So, to fix the issues, scientist devised 1's complement.
1's Complement
| Binary | Decimal |
| :-----: | :-----: |
| 1 0 0 0 | -7 |
| 1 0 0 1 | -6 |
| 1 0 1 0 | -5 |
| 1 0 1 1 | -4 |
| 1 1 0 0 | -3 |
| 1 1 0 1 | -2 |
| 1 1 1 0 | -1 |
| 1 1 1 1 | -0 |
| 0 0 0 0 | +0 |
| 0 0 0 1 | +1 |
| 0 0 1 0 | +2 |
| 0 0 1 1 | +3 |
| 0 1 0 0 | +4 |
| 0 1 0 1 | +5 |
| 0 1 1 0 | +6 |
| 0 1 1 1 | +7 |
In this, everything from +0 to +7 is the same as before. The difference is with the negative numbers. We take the positive number's binary, and we complement all the bits. So, 0 becomes 1 and 1 becomes 0.
You can see for e.g., +5 and -5, the former is 0 1 0 1 and the latter is 1 0 1 0.
So, now if we add +5 and -5 like before 0 1 0 1 and 1 0 1 0, it gives 1 1 1 1 which is -0.
But here also, we have some issues,
There still is +0 and -0.
Let's try adding +5 and -3 that's 0 1 0 1 and 1 1 0 0, adding them we get, 1 0 0 0 1. Again, ignoring the first 1, we get 0 0 0 1
and that's +1 but it should be +2. Similarly, if we add +6 and -2 we should get +4 but adding 0 1 1 0 and 1 1 0 1, we get 1 0 0 1 1 i.e., 0 0 1 1 which is +3.
So, if we add +1 to all the answers, the answers becomes correct. 0 0 1 1 + 1 is 0 1 0 0 which is +4.
2's Complement
This method is very similar to 1's complement.
| Binary | Decimal |
| :------: | :----------: |
| -8 4 2 1 | place values |
| 1 0 0 0 | -8 |
| 1 0 0 1 | -7 |
| 1 0 1 0 | -6 |
| 1 0 1 1 | -5 |
| 1 1 0 0 | -4 |
| 1 1 0 1 | -3 |
| 1 1 1 0 | -2 |
| 1 1 1 1 | -1 |
| 0 0 0 0 | +0 |
| 0 0 0 1 | +1 |
| 0 0 1 0 | +2 |
| 0 0 1 1 | +3 |
| 0 1 0 0 | +4 |
| 0 1 0 1 | +5 |
| 0 1 1 0 | +6 |
| 0 1 1 1 | +7 |
What this method does is, it gets rid of the -0 and therefore, we have -8. So, 0 1 1 1 1 1 1 1 i.e., 127 becomes 1 0 0 0 0 0 0 0 i.e., 127 -128 because 0 to 127 is 128 and -1 to -128 is 128. Hence, 2^8 = 256.
And, if we add 2 numbers just like before +5 and -5 i.e., 0 1 0 1 and 1 0 1 1 we get 1 0 0 0 0 i.e., 0 0 0 0 which is exactly 0. No weird -0 and +0. Let's take another example i.e +6 and -2 i.e., 0 1 1 0 and 1 1 1 0, we get 1 0 1 0 0 i.e., 0 1 0 0 which is 4. YAY!.
But that's not all, 2's complement packs even more logic. In the above table you can see the Least significant bit i.e., the right most bit is 1 i.e., 2^0 and then 2 i.e., 2^1 and then 4 i.e., 2^2 but then -8 i.e., -2^3. So, if we take -5 as example, we get 1 0 1 1 i.e., (1 * -2^3) + (0 * 2^2) + (1 * 2^1) + (1 * 2^0) i.e., -8 + 0 + 2 + 1 which is -5. Maths is the real magic here.
Now, to negate the number +5 for example. We have to do 2 steps, instead of 1 like the previous methods.
We have to take complement (invert) i.e., 0 1 0 1 becomes 1 0 1 0.
Then, we have to add 1 i.e., 1 0 1 0 + 1 so, it becomes 1 0 1 1 which is -5.
This method works great, and we get an extra number to store. That's the reason a normal int (32 bit) in C++ has a range of 2^31 to 2^31 - 1.

Related

Bar chart from many variables where varx = in Stata

I have a bar chart question here. Given that for all the variables in the dataset 1 = yes and 0 = No. I would like to plot a bar graph with the percentages (where var=1) on the y-axis and the variables on the x axis. Thanks in advance.
Dataset
Water
Ice
Fire
Vapor
1
1
0
1
1
0
0
1
0
1
1
1
1
1
1
1
1
1
0
1
1
1
1
0
0
1
1
1
0
1
0
1
0
1
1
1
1
0
1
1
0
1
0
0
0
1
1
0
1
0
1
0
1
0
1
0
1
1
1
1
0
1
0
1
1
0
1
1
1
0
1
0
1
1
0
1
1
0
0
1
0
1
1
1
1
1
0
1
1
0
0
1
0
1
1
1
The percent of 1s in a (0, 1) variable is just the mean multiplied by 100. As you probably want to see the percent as text on the graph, one method is to clone the variables and multiply each by 100.
You could then use graph bar directly as it defaults to showing means. I don't like its default in this case and the code instead uses statplot, which must be installed before you can use it.
* Example generated by -dataex-. For more info, type help dataex
clear
input byte(water ice fire vapor)
1 1 0 1
1 0 0 1
0 1 1 1
1 1 1 1
1 1 0 1
1 1 1 0
0 1 1 1
0 1 0 1
0 1 1 1
1 0 1 1
0 1 0 0
0 1 1 0
1 0 1 0
1 0 1 0
1 1 1 1
0 1 0 1
1 0 1 1
1 0 1 0
1 1 0 1
1 0 0 1
0 1 1 1
1 1 0 1
1 0 0 1
0 1 1 1
end
quietly foreach v of var water-vapor {
clonevar `v'2 = `v'
label var `v'2 "`v'"
replace `v'2 = 100 * `v'
}
* ssc install statplot
statplot *2 , recast(bar) ytitle(%) blabel(bar, format(%2.1f))
Try
. ssc install mylabels
checking mylabels consistency and verifying not already installed...
all files already exist and are up to date.
. sysuse nlsw88, clear
(NLSW, 1988 extract)
. mylabels 0(10)70, myscale(#/100) local(labels)
0 "0" .1 "10" .2 "20" .3 "30" .4 "40" .5 "50" .6 "60" .7 "70"
. graph bar (mean) married collgrad south union, showyvars legend(off) nolabel bargap(20) ylabel(`labels')
. table, statistic(mean married collgrad south union)
------------------------------
Married | .6420303
College graduate | .2368655
Lives in the south | .4194123
Union worker | .2454739
------------------------------
This relies on mylabels, and implements the bar gap (which I also like).

Sorting issue with limit and offset MYSQL

I am facing sorting issue in mysql
See the output of below query:
select astrologers.id,astrologers.name,chat_online,online,experience from `astrologers`
where `astrologers`.`status` = '1'
order by experience asc limit 10;
id
name
chat_online
online
experience
15
Astro Anoop
0
0
3
20
Test Astro2
0
0
3
3
Test anoop
0
0
5
4
Anoop Kumar trivedi
0
0
5
7
Test
0
0
5
58
Neeraj yadav
1
0
5
45
Satish Kumar Gupta
1
1
10
56
AP Sharma
1
0
15
40
VG Astrologer App
1
0
55
In above result id 58 (Neeraj yadav) is at 6th position but when I run the same query with limit 3, same id 58 (Neeraj yadav) is at 3rd position:
select astrologers.id,astrologers.name,chat_online,online,experience
from `astrologers`
where `astrologers`.`status` = '1'
order by experience asc limit 3;
id
name
chat_online
online
experience
20
Test Astro2
0
0
3
15
Astro Anoop
0
0
3
58
Neeraj yadav
1
0
5
The 3rd row in above result should be id 3 (Test anoop) but it gives id 58 (Neeraj yadav)
Is this bug in mysql?
Is this a bug in MySQL?
No. The problem is that your sort is not deterministic, and gives ties in the third position:
| 3 | Test anoop | 0 | 0 | 5 |
| 4 | Anoop Kumar trivedi | 0 | 0 | 5 |
| 7 | Test | 0 | 0 | 5 |
| 58 | Neeraj yadav | 1 | 0 | 5 |
All 4 users have the same experience, hence leaving the database to figure out how they should be sorted.
When asked to return to top 3 rows, the database picks the first two, and then one of the 4 ties. The result that you get might not be consistent over consequent executions of the same query, as you are starting to see.
Bottom line: know you data; if you want a deterministic result, then use a deterministic sort. We could, for example, use id to break the ties, hence making the result predictable:
order by experience, id limit 3

MySQL update col4 based on whether value from col1 exists in col2 and col3 = value

I have a table (named units) with the below structure:
id type type_id name parent hide
====================================================
12 child 2 no1-r 36 0
32 child 2 no2-l 0 0
36 parent 1 no1 0 0
42 parent 1 no4 0 0
59 child 2 no5-t 0 0
60 child 2 no6-r 72 0
63 child 2 no6-l 72 0
72 parent 1 no6 0 0
81 parent 1 no7 0 0
94 parent 1 no8 0 0
95 parent 1 no9 0 0
97 child 2 no9-r 95 0
99 child 2 no9-t 95 0
What I want to do is iterate through all id's and if id does not exist in parent and type_id = 1 then set hide to 1. So my output table would result as:
id type type_id name parent hide
====================================================
12 child 2 no1-r 36 0
32 child 2 no2-l 0 0
36 parent 1 no1 0 0
42 parent 1 no4 0 1
59 child 2 no5-t 0 0
60 child 2 no6-r 72 0
63 child 2 no6-l 72 0
72 parent 1 no6 0 0
81 parent 1 no7 0 1
94 parent 1 no8 0 1
95 parent 1 no9 0 0
97 child 2 no9-r 95 0
99 child 2 no9-t 95 0
So basically because id's 42, 81 and 94 do not exist in parent their hide value is set to 1. Whereas, id 36 does exist in parent so isn't affected and also id 32 isn't affected even though it does not exist in parent because its type_id is 2.
I cannot for the life of me wrap my head around what MySQL (running ver 5.6.44) update to run on this table to achieve this output, so any help would be greatly appreciated!
You can do it with a self LEFT join in the UPDATE statement:
UPDATE units u1
LEFT JOIN units u2 ON u2.parent = u1.id
SET u1.hide = 1
WHERE u1.type_id = 1 AND u2.id IS NULL
See the demo.
Results:
> id | type | type_id | name | parent | hide
> -: | :----- | ------: | :---- | -----: | ---:
> 12 | child | 2 | no1-r | 36 | 0
> 32 | child | 2 | no2-l | 0 | 0
> 36 | parent | 1 | no1 | 0 | 0
> 42 | parent | 1 | no4 | 0 | 1
> 59 | child | 2 | no5-t | 0 | 0
> 60 | child | 2 | no6-r | 72 | 0
> 63 | child | 2 | no6-l | 72 | 0
> 72 | parent | 1 | no6 | 0 | 0
> 81 | parent | 1 | no7 | 0 | 1
> 94 | parent | 1 | no8 | 0 | 1
> 95 | parent | 1 | no9 | 0 | 0
> 97 | child | 2 | no9-r | 95 | 0
> 99 | child | 2 | no9-t | 95 | 0

Why bitshift when evaluating truth tables as binary numbers?

The last answer in this question shows that a binary truth table can be represented as a binary number:
0 0 0 | 1
0 0 1 | 1
0 1 0 | 0
0 1 1 | 0
1 0 0 | 1
1 0 1 | 0
1 1 0 | 1
1 1 1 | 0
Can be represented by 01010011.
The entries in the table can also be evaluated using this number.
def evaluate(f, x):
return (f & (1<<x)) != 0
f = int('01010011',2)
>>> evaluate(f,int('100',2))
True
>>> evaluate(f,int('101',2))
False
My question is about the evaluate function provided by the answer. Why must we left shift the bits by one?
You have it backwards. It is the binary number 1 shifted left by x spots.
And that should make sense. If you want to check the 4th spot in the table, represented by f, you have to check that f & 10000!=0.
You're right, shifting by one is very arbitrary and does not make sense.

Mysql Between Clause inside Case when statement and count number of items in column

Here i am trying to get the count of products by using case when in mysql .
My sample data is
ID | Proname | led | lcd | hd | fullhd | 3d | displaysize (inches) | brandID
1 tv1 1 0 0 1 0 22 3
2 tv2 0 1 1 0 0 26 3
3 tv3 1 0 1 0 0 32 3
4 tv4 1 0 0 1 1 55 3
5 tv5 1 0 0 1 0 42 3
Now my expected out put
lcdcnt | ledcnt | hdcnt | fullhdcnt | 3dcnt | dispcntlessthan32 | displaycntbetwwen32and42 | displaycntabove42
1 4 2 3 1
Here is my Query . but i am not getting the correct output as i expected
select
sum(lcdtv) lcdcnt,
sum(ledtv) ledcnt,
sum(3dtv) 3dcnt,
sum(plasmatv) plasmacnt,
sum(smarttv) smatcnt,
sum(hdtv) hdnt,
sum(fullhdtv) fullhdcnt,
sum(ultrahdtv) ultrahdcnt,
sum(4ktv) 4kcnt,
sum(8ktv) 8kcnt,
sum(oledtv) oledcnt,
case
when (displayinches between 1 and 32) then count(displayinches)
end as dispcntlessthan32
case
when (displayinches between 32 and 42) then count(displayinches)
end as displaycntbetwwen32and42
from
tv
where
brandID = 3 and (ledtv = 1) and price != 0
Here is the SQLFiddel Demo
Below is the Approach :
select
sum(lcd) lcdcnt,
sum(led) ledcnt,
sum(3d) 3dcnt,
sum(hd) hdnt,
sum(fullhd) fullhdcnt,
sum(3d) 3dcnt,
sum(case when displaysize between 1 and 32 then 1 else 0 end) as dispcntlessthan32,
sum(case when displaysize between 33 and 42 then 1 else 0 end) as displaycntbetween32and42
from table1
where brandID = 3