I looked a couple of different way to convert binary to integer in JAVA.
But I couldn't figure out why this works?
int res = 0;
res += 1 << 1;
The res turns out to be 2, I know it shifts towards left 1 bit and became 10 in binary. But I'm confusing how it converts from binary to integer, i want to know the mechanism.
Thanks
First of all, let's clear up some terminology first. What you believe to be an integer is actually a number in the base 10 notation, which in case of Java is a natural number that is represented using the ten digits from 0 to 9 (hence base 10).
In binary notation we are dealing with just two digits instead to represent all natural numbers. Both binary (base 2) and decimal numbers (base 10) are integers.
Digit shifting is multiplication or division by the base of the number
The bit shifting effect you observed can be easily explained using base 10 numbers you are already familiar with. Imagine you have a strip of square fields pre-filled with 0s. In each field you can write a digit from 0 to 9, and lets assume these fields are called "bits". You write the number 7 into that strip aligned to the right hand side:
0|0|0|0|0|7
Imagine that whole strip represents the integer 7 now. What bit shifting effectively does, is moving those digits in that strip either to the left or the right, while filling up the previously occupied spots with 0s. Imagine, we are shifting our 7 to the left by one spot:
0|0|0|0|7|0
By shifting the number to the left we practically performed a quick multiplication by 10 (remember, that is the base of our numeral system we're dealing with here).
When you shift that number to the right by one spot, you perform a division by 10.
Bit shifting is multiplication or division by 2
The same applies to binary numbers, the dominant storage format for numbers in computers. Binary numbers are comprised of just two digits, 1s and 0s.
Just take a quick look at the following table for getting a better understanding of binary numbers:
+-------------------+
| Decimal | Binary |
+---------+---------+
| 0000001 | 0000001 |
| 0000002 | 0000010 |
| 0000003 | 0000011 |
| 0000004 | 0000100 |
| 0000005 | 0000101 |
| 0000006 | 0000110 |
| 0000007 | 0000111 |
| ... | ... |
+---------+---------+
We perform multiplications by 2 when we shift the number in our strip to the left, and we perform divisions by 2 when we shift the number to the right. Just check out the table, and look up the decimal number 1. Multiply it by 2 and look at the binary representation. Multiply that again by 2 (decimal 4) and look at the binary notation. The binary digit 1 just moves to the left one by one due to the multiplication by two.
res+= 1<<1; can be written as res = res + 1<<1;
if you take 1<<1 which means 1 is represented as 0x00000001 = 00000000 00000000 00000000 00000001
when you do a right shift it becomes 00000000 00000000 00000000 00000010
which is 0x00000002 which is 2 in decimal value
Related
All of us know that Integer datatype can store values till 4 bytes, means 32 bits
so for example if we have
int a = 2;
it means a = 00000000 00000000 00000000 00000010
Is there any way to use the remained bits and store value in them and take them out when needed?
Let me take another example:
We have a computer system that only uses English alphabets and numbers (26 + 10), so the sum of them is 36.
Like when when we have 256 characters in computer and log_2(256) = 8 bits and we use 8 bits to store values
log_2(36)= 6 bits
it means that 6 bit is enough for the values.
Here is the question:
how I can use only three bytes to store 4 characters in it?
base on log2(36) = 6
this photo can show the idea better
Base64
The Base64 encoding is exactly what you want, and it has Java implementations. From the Wiki
Each Base64 digit represents exactly 6 bits of data. Three 8-bit bytes (i.e., a total of 24 bits) can therefore be represented by four 6-bit Base64 digits.
Java8's docs include Base64 here.
Old, Unnecessarily Complicated Answer
To answer your question in particular, you can cram four characters into three bytes using bit shifting and a custom binary encoding.
For example, if you were to encode the lowercase letters of the alphabet and digits as six-bit codes
Symbol | Decimal | Binary
0 | 0 | 000000
1 | 1 | 000001
...
f | 16 | 010000
...
o | 25 | 011001
...
z | 35 | 100011
...
EOF | 63 | 111111
Then the string foof could be written as 010000 011001 011001 010000. Most languages would prefer to represent this as three bytes, or 01000001 10010110 01010000. This is A搀 using the utf-8 binary encoding or -63 22 -48 if you represent them as the byte type in Java.
I'm not terribly familiar with Java, but I know there are several resources for C and other languages to read off the exact bit-values for some bytestream.
Since I started using eclipse for project euler, I noticed that big numbers sometime become a seemingly random negative numbers. I suppose this has something to do with passing the boudry of the type.
I'll be glad if you could explain to me how these negative numbers are generated and what is the logic behind it. Also, how can I avoid them (preferable not with BigInteger class). Danke!=)
This image shows what you're looking for. In your case it's obviously larger numbers, but the principle stays the same.
Examples of limits in java are:
int: −2,147,483,648 to 2,147,483,647.
long: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
In the image 0000, 0001 etc, shows the binary representation of the numbers.
EDIT: In project euler you often have to think of a way to work around the lagre numbers. The problems are designed with numbers that big so that you can't use the ordinary way of problem solving. However, if you find that you really need to use them, i suggest studying BigInteger anyway. You will find it useful in the long run, and it's not all that complicated. Here is a link with lots of understandable examples:
BigInteger Example
In mathematics numbers are infinite. However in computers they are not. There is MAX_VALUE for each int-like type: int, short, long. For example Integer.MAX_VALUE. When you try to increase number more than this value the number becomes negative. This way the internal binary representation of numbers work.
int i = Integer.MAX_VALUE;
i++; // i becomes negative.
Here's a two's complement representation for 2-bit integer: (U means Unsigned, S means Signed)
U | bits | S
---------------
0 | 00 | 0
1 | 01 | 1 \ overflow here:
2 | 10 | -2 / 1 + 1 = -2
3 | 11 | -1
Arithmetic is done mostly like in the unsigned case, modulo max(U) (4 in our case).
The logic is the same for bigger types. int in Java is 32 bit. Use long for 64 bits.
You are probably overflowing the size of your data type, since the most significant bit is the sign bit. I don't think that Java has unsigned data types, so you may try using a larger data type such as long if you want to hold bigger numbers than int. If you are still overflowing a long though, you're pretty much stuck with BigInteger.
I am very confused on right shift operation on negative number, here is the code.
int n = -15;
System.out.println(Integer.toBinaryString(n));
int mask = n >> 31;
System.out.println(Integer.toBinaryString(mask));
And the result is:
11111111111111111111111111110001
11111111111111111111111111111111
Why right shifting a negative number by 31 not 1 (the sign bit)?
Because in Java there are no unsigned datatypes, there are two types of right shifts: arithmetic shift >> and logical shift >>>. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
Arithmetic shift >> will keep the sign bit.
Unsigned shift >>> will not keep the sign bit (thus filling 0s).
(images from Wikipedia)
By the way, both arithmetic left shift and logical left shift have the same result, so there is only one left shift <<.
Operator >> called Signed right shift, shift all the bits to right a specified number of times. Important is >> fills leftmost sign bit (Most Significant Bit MSB) to leftmost bit the after shift. This is called sign extension and serves to preserve the sign of negative numbers when you shift them right.
Below is my diagrammatic representation with an example to show how this works (for one byte):
Example:
i = -5 >> 3; shift bits right three time
Five in two's complement form is 1111 1011
Memory Representation:
MSB
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
+----+----+----+---+---+---+---+---+
7 6 5 4 3 2 1 0
^ This seventh, the left most bit is SIGN bit
And below is, how >> works? When you do -5 >> 3
this 3 bits are shifted
out and loss
MSB (___________)
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
+----+----+----+---+---+---+---+---+
| \ \
| ------------| ----------|
| | |
▼ ▼ ▼
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
+----+----+----+---+---+---+---+---+
(______________)
The sign is
propagated
Notice: the left most three bits are one because on each shift sign bit is preserved and each bit is right too. I have written The sign is propagated because all this three bits are because of sign(but not data).
Also because of three right shift right most three bits are losses out.
The bits between right two arrows are exposed from previous bits in -5.
I think it would be good if I write an example for a positive number too. Next example is 5 >> 3 and five is one byte is 0000 0101
this 3 bits are shifted
out and loss
MSB (___________)
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
+----+----+----+---+---+---+---+---+
| \ \
| ------------| ----------|
| | |
▼ ▼ ▼
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+----+----+----+---+---+---+---+---+
(______________)
The sign is
propagated
See again I writes The sign is propagated, So leftmost three zeros are due to sign bit.
So this is what operator >> Signed right shift do, preserves the sign of left operand.
[your answer]
In your code, you shifts -15 to right for 31 times using >> operator so your right most 31 bits are loosed and results is all bits 1 that is actually -1 in magnitude.
Do you notice that In this way -1 >> n is equivalent to not a statement.
I believe if one do i = -1 >> n it should be optimized to i = -1 by Java compilers, but that is different matter
Next, It would be interesting to know in Java one more right shift operator is available >>> called Unsigned Right Shift. And it works logically and fills zero from left for each shift operation. So at each right shift you always get a Zero bit on left most position if you use unsigned right shift >>> operator for both Negative and Positive numbers.
Example:
i = -5 >>> 3; Unsigned shift bits right three time
And below is my diagram that demonstrates how expression -5 >>> 3 works?
this 3 bits are shifted
out and loss
MSB (___________)
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
+----+----+----+---+---+---+---+---+
| \ \
| ------------| ----------|
| | |
▼ ▼ ▼
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
+----+----+----+---+---+---+---+---+
(______________)
These zeros
are inserted
And you can notice: this time I am not writing that sign bits propagated but actually >>> operator insert zeros. Hence >>> doesn't preserves sign instead do logical right shift.
In my knowledge unsigned right shift is useful in VDU (Graphics programming),Although I haven't used it but read it some where in past.
I would suggest you read this: Difference between >>> and >> : >> is arithmetic shift right, >>> is logical shift right.
Edit:
Some interesting about Unsigned Right Shift Operator >>> operator.
The unsigned right shift operator >>> produces a pure value that is its left operand right-shifted with zero 0 extension by the number of bits specified by its right operand.
Like >> and <<, operator >>> also operator never throws an exception.
The type of each operand of the unsigned right shift operator must be an integer data type, or a compile-time error occurs.
The >>> operator may perform type conversions on its operands; unlike arithmetic binary operators, each operand is converted independently. If the type of an operand is byte, short, or char, that operand is converted to an int before the value of the operator is computed.
The type of the value produced by the unsigned right shift operator is the type of its left operand. LEFT_OPERAND >>> RHIGT_OPERAND
If the converted type of the left operand is int, only the five least significant bits of the value of the right operand are used as the shift distance. (that is 25 = 32 bits = number of bit in int)
So, the shift distance is in the range 0 through 31.
Here, the value produced by r >>> s is the same as:
s==0 ? r : (r >> s) & ~(-1<<(32-s))
If the type of the left operand is long, then only the six least significant bits of the value of the right operand are used as the shift distance.(that is 25 = 64 bits = number of bit in long)
Here, the value produced by r >>> s is the same as the following:
s==0 ? r : (r >> s) & ~(-1<<(64-s))
A Interesting Reference: [Chapter 4] 4.7 Shift Operators
Because >> is defined as an arithmetic right shift, which preserves the sign. To get the effect you expect, use a logical right shift, the >>> operator.
|---|---|---|---|---|
| 1 | 1 | 3 | 5 | 1 |
|---|---|---|---|---|
| 3 | 3 | 2 | 0 | 3 |
|---|---|---|---|---|
| 3 | 0 | 3 | 2 | 3 |
|---|---|---|---|---|
| 1 | 4 | 0 | 3 | 3 |
|---|---|---|---|---|
| 3 | 3 | 3 | 1 | 1 |
|---|---|---|---|---|
(Figure 1)
Figure 1 shows a square. Each row, each column and the two diagonals can be read as a five digit prime number. The rows are read from left to right. The columns are read from top to bottom. Both diagonals are read from left to right. Using the data in the INPUT.TXT file, write a program that constructs such squares.
The prime numbers must have the same digit sum (11 in the example).
The digit in the top left-hand corner of the square is pre-determined (1 in the example).
A prime number may be used more than once in the same square.
If there are several solutions, all must be presented.
A five digit prime number cannot begin with zeros, ie 00003 is NOT a five digit prime number.
Input Data
11
1
I am attempting to do a question from IOI'94 Competition - Problem 3 - The Primes.
I have built most of the helper functions...
Used Sieve of Eratosthenes to generate 5 digit primes (between 9999 & 100000)
Built a function to compute the sum of digits (12345 = 1+2+3+4+5 = 15)
Built a function to check an array if the sum of digits are the same throughout
Built a function to check if a number startsWith a specified digit (startWith(12345,1) return true)
Question: The issue is I don't know how to full the array or use the backtracking capability to keep checking :(. Can anyone help me please? How to I go about filling the 2D array so that it contains values from the prime table and the sum is correct on all angle?
*NB: The Sieve of Eratosthenes method that generates the 5 digit prime, also as the capability of filtering values that starts with X and values sum up to M *
Complete question : http://olympiads.win.tue.nl/ioi/ioi94/contest/day1prb3/problem.html
Prospective order of adding values, just don't know how to do it :(.
1 2 3 4 5
6 13 14 12 15
7 16 11 18 19
8 10 20 22 23
9 17 21 24 25
From what you write I assume that you have a list of 5 digit prime numbers already.
Filter the list so that it contains only the primes with the right sum of digits.
You'll need a function valid to check for a valid square, given 1 to 5 numbers that go in the columns. (It is clear that the column numbers determine the other rows and diagonals. So, if the 3rd digit of the 1st column is a 7, but there is no prime that starts with 7, we know that we can't use this prime in the first column. Without looking at all the other numbers, this will prune your search tree early.)
You need another function to get sets of all valid prime numbers that have a certain digit at position n (1..5). Perhaps you want to precalculate this and store it in some tree or array.
The major work is done in valid, which must check whether there exist prime numbers for the rows and diagonals with the digits in the positions determined so far by the primes in the columns.
Then the list of solutions is:
[ (c1, c2, c3, c4, c5) | c1 <- primes, valid [c1],
c2 <- primes, valid [c1,c2],
c3 <- primes, valid [c1,c2,c3],
c4 <- primes, valid [c1,c2,c3,c4],
c5 <- primes, valid [c1,c2,c3,c4,c5] ]
or, put imperatively:
for each c1 in primes
if valid(c1) then foreach c2 in primes
if valid(c1,c2) then foreach c3 in primes
if valid(c1,c2,c3) then foreach c4 in primes
if valid(c1,c2,c3,c4) then foreach c5 in primes
if valid(c1,c2,c3,c4,c5) then print solution
Addendum: Since we need only to look for numbers that begin with a seqeuence of certain digits, the solution can be made more efficient.
Consider the case that c1,c2, annd c3 are given and valid() is about to check row 3. It takes the 3rd digit of c1, c2 and c3 and we can interpret these as the leading 3 digits of the number that must appear in row 3. We need only to fill it up with zeroes and can then check if we know a prime number that is greater than this number, but the difference must be lower than 100 (so that the leading digits are preserved). But if we have a sorted array of prime number candidated, this requires not more than a binary search in that array.
Okay, I tried looking up what >>, or shift means, but it's way over my head as this site explains it: http://www.janeg.ca/scjp/oper/shift.html
What would the explanation be, if talking to a kid?
Computers are binary devices. Because of this, numbers are represented by a sequence of 1s and 0s.
Bitshifting is simply moving those sequences of 1s and 0s left or right.
So all the >> operator does is shift the bits towards the right one bit.
Consider the number 101:
// Assuming signed 8-bit integers
01100101 // How 101 is represented in binary
00110010 // After right shifting one bit, this represents 50
The least significant bit in this case was truncated. Obviously the devil's in the details, but that's all there is really to it.
The << operator does the opposite operation:
// Assuming signed 8-bit integers
01100101 // How 101 is represented in binary
11001010 // After left shifting one bit, this represents -54
// Assuming unsigned 8-bit integers
01100101 // How 101 is represented in binary
11001010 // After left shifting one bit, this represents 202
In this case, the most significant bit was truncated since I used only 8-bits. If the number had more bits, however:
// Assuming signed 16-bit integers
00000000 01100101 // How 101 is represented in binary
00000000 11001010 // After left shifting one bit, this represents 202
00000001 10010100 // After left shifting one bit again, this represents 404
So you may get different numbers depending on how many bits and the data types associated with those bits you're dealing with.
Addendum: If you're wondering how binary works, think about how the decimal number system works. Consider the number 5287. It can be written like this:
5287
But you can also write it out like this:
5287 = (5 * 1000) + (2 * 100) + (8 * 10) + (7 * 1)
Which you can then write out like this:
5287 = (5 * 10^3) + (2 * 10^2) + (8 * 10^1) + (7 * 10^0)
The above equation explains why the decimal number system is sometimes called the base-10 system. The decimal number system employs the use of 10 digits (0-9). Notice how the exponents correspond to digit position.
The binary number system, or the base-2 system, is the exact same thing but with the number two as the base of the exponents, and employing only two digits: 0 and 1.
5287 = 00010100 10100111 (base 2)
= (0 * 2^15) + (0 * 2^14) + (0 * 2^13) + (1 * 2^12)
+ (0 * 2^11) + (1 * 2^10) + (0 * 2^9) + (0 * 2^8)
+ (1 * 2^7) + (0 * 2^6) + (1 * 2^5) + (0 * 2^4)
+ (0 * 2^3) + (1 * 2^2) + (1 * 2^1) + (1 * 2^0)
Can I assume the kid I'm talking to knows a bit about binary? :)
All numbers can be represented in some kind of binary, like so:
Base 10 : Base 2
1 : 0001
2 : 0010
3 : 0011
4 : 0100
5 : 0101
6 : 0110
7 : 0111
8 : 1000
...
and so on.
The shift operators basically move all of the bits (1s or 0s) across one position. So, for example:
000111 >> 1
shifts all the bits in 000111 right by one number to produce this:
000011
000111 << 1
shifts all those bits left by one, to produce this:
001110
If you shift by more than one, then it just moves the bits further.
Now, depending on what language you're using and the kind of numbers you're working with, it can be a little bit more complicated than that. For example, if you are working in a language where the "most significant bit" (the one furthest to the left in a number) represents whether the number is signed or not, then the language will have to take that into account.
Mathematically speaking, if you take an integer (and ignore the risk of overflows, which are caused by the computer running out of space to store bits,) shift left by 1 (<< 1) is the equivalent of multiplying by 2, and shift right by 1 is the equivalent of dividing by 2. (Think a bit about what a "place value" in binary maths is worth, and that'll make sense)
>> the SHIFT RIGHT operator
Example:
class X
{
public static void main(String args[])
{
System.out.println("20>>2 = "+20>>2);
}
}
Output : 20>>2 = 5
Explanation:
Binary value of 20 is: 00000000000000000000000000010100
shift all bits 2 positions to right 00000000000000000000000000000101
It will give 5 ( 1*2^2 + 0*2^1 + 1*2^0 )
I once wrote an JApplet (bitorgel) and put it on my web page, where one can play around with bit operators. You can try it live, or download the source. AFAIK they work the same in C, C++ and Java - probably in C# too.