I am very new to Java (4 weeks, 4 days a week), with zero prior programming knowledge. Can someone explain how this prints 32?
int a = 10;
a = a++ + a + a-- - a-- + ++a;
System.out.println(a);
a++ > means use then change .. So value of a is used first = 10 and then incremented = 11
++a > means change then use. So value of a is first changed then used.
So a = a++ + a + a-- - a-- + ++a;
= (10)
+ (11 [since a is incremented after use])
+ 11 [since a-- = use then change = 11, after -- becomes 10]
- 10 [since value of a is now decremented, and then decremented again, so a = 9 at this point]
+ 10 [since ++a is change then use]
in summary
a = 10 + 11 + 11 - 10 + 10 = 32.
Hope it helps :)
Let's take this one step at a time.
a++ will increment a by one.
a++ +a will take the (11)+ the existing a(10), to give 21
Another iteration will set a to 30, with a decremented by 1 at the end.
- a-- will subtract 1 from a, and subtract this from the value. So -9,
This one is the real trick. a is incremented before any other operation starts. So a becomes 11, before everything else even calculates.
Bottom line, this simplifies to:
4*a-a-2+1= 3*a-1, where a=11 because it has been incremented before anything started (++a).
If instead you moved the ++ to the other side of the ++a, you'd have 29, which is much easier to understand where it comes from.
Easy:
a = 10 + 11 + 11 - 10 + 10 = 32.
It's clearer with parentheses added:
a = (a++) + (a) + (a--) - (a--) + (++a);
The ++ and -- are evaluated based on where they are in relation to the variable, if it is a++ then a is first evaluated, then it is incremented. If you have ++a, then a is incremented and then evaluated.
So a++ + b will take a and add it to be, and then increment it,
while,
++a + b will first increment a, and then add it to b.
In simple
public static int i = 10;
is indicating that the integer i has a value of 10.
then saying
i++;
will make i's value 11, so it just like saying 10 + 1
saying
i--;
will makes i's value 9, so its like saying 10 - 1.
then
i = i + 1;
will do the same as i++;
but its used like i = i + 20; in most cases to take its value and add 20 to it.
same for
i = i - 20;
but taking away instead of adding.
then
a + a;
that will double a.
Hope this helps, Luke.
Related
This question already has answers here:
How do the post increment (i++) and pre increment (++i) operators work in Java?
(14 answers)
Closed 1 year ago.
New to JAVA, and I know there have been some discussions about ++i and i++, but I still don't know how to approach the question below and how to explain the answer. I shared what I think, but I hope you can help correct what's wrong with my thinking. Thank you very much!
The question is:
Give the results of the following java program.
int z = -1;
system.out.println(++z);
(My thinking: pre-increment, which is incrementing the value of i by 1, so the output is -1+1 = 0)
system.out.println(z--);
(My thinking: pre-decrement, which is decrementing the value of i by 1, so the output is -1-1 = -2, but why is 0? )
system.out.println(z++ + z);
(My thinking: post-increment, which is incrementing the value of i by 1.So the entire thing reads as (z++ plus z). So z++ is 0, + (plus) z, which is 0 + (-1), so the output is -1)
system.out.println(z + z++);
(My thinking: the entire thing reads as (z plus z++). So z is -1, plus z++, which is 0, so the output is -1, but the answer is 0.)
The answer is: 0 0 -1 0
What the answer would be if we changed every + to -?
int z = -1;
system.out.println(--z);
system.out.println(z-- - z);
system.out.println(z - z--);
After reading lots of discussions, I still feel confused. Really hope to learn to understand the concepts. Thank you!
(My thinking: pre-decrement, which is decrementing the value of i by
1, so the output is -1-1 = -2, but why is 0? )
Its not pre-decreement, its post-decreement. For clarity :
++a -> pre-increement
a++ -> post-increement
--a -> pre-decreement
a-- -> post-decreement
int z = -1;
System.out.println(++z);
// ++(-1) => 0; z = 0
System.out.println(z--);
// (0)-- => 0; z = -1
System.out.println(z++ + z);
// (-1)++ + (0) => -1; z = 0
System.out.println(z + z++);
// (0) + (0)++ => 0; z = 1
What the answer would be if we changed every + to -?
I think it would be a nice exercise for you, try it on our own and check by writing a java program for it
The major difference between per-increment and post-increment operation is that the time assignment takes place. in pre-inc operation increment happens before operation. but in post increment first operation then increment. Try to run the below code.
System.out.println(++z);// ++z means z=z+1 hence o/p 0
System.out.println(z--); here first print value 0. then increment happens
System.out.println(z);//here you will get the value -1
System.out.println(z++ + z);//now the value of z is-1 value inc+z 's value
//-1+0 will give -1
System.out.println(z);// assignment happens later here value is 0
System.out.println(z + z++);//0+0=prints 0 later increment
System.out.println(z);// final value for z is 1
I have a simple Java expression depicted below. Based on Operator Precedence table, I expect that this expression would return division by zero exception (since post-fix increment operator has highest priority) and expect that resulting expression would look like:
2 + 2 + 5 / 0
But result is 7, why ? (By little bit of experimentation I found that all operators are assigned value of 1 for some reason, but this does not make sense to me in case priority table is correct)
int intCountOperator = 0;
unaryOperand = ++intCountOperator + intCountOperator + 5 / intCountOperator++;
System.out.println(unaryOperand); // Prints 7
The operator precedence does not control the evaluation order. It controls only how the expression is to be read. For example, since multiplication has a higher precedence than addition, x + y * z is read as x + (y * z), not (x + y) * z. However, it does not change that first x is evaluated, then y and finally z.
Giving a good example with ++ and -- is more difficult, because there is usually only one reading which makes sense. However, you might notice that y - x++ compiles without error (if x and y are numerical variables). If ++ would have had a lower precedence than - it would be evaluated as (x - y)++ which would not compile.
Because of operator precedence, your expression is evaluated as:
(++intCountOperator) + (intCountOperator + (5 / (intCountOperator++)));
but the evaluation order is not changed by it.
The expression is evaluated from left to right :
unaryOperand = ++intCountOperator + intCountOperator + 5 / intCountOperator++;
1 + 1 + 5 / 1 = 7
Note that the operators are evaluated in the order you expect, i.e. 1 + 1 + (5/1) = 1 + 1 + 5 = 7, but the operands of all those expressions are evaluated from left to right.
The order of evaluation is from left to right and not right to left. So the result 7 which you are getting is correct.
unaryOperand = ++intCountOperator + intCountOperator + 5 / intCountOperator++;
is actually
unaryOperand = 1 + 1 + 5 / 1; = 7
I was messing with i++ when I stumbled upon i+++[another expression]. I went and tested it in DrJava:
> int i;
> i++
0
> i+++1
2
> i+++1
3
> i+++2
5
> i+++1
5
> ++i+1
7
> ++i+1
8
> ++i+1
9
> ++i+2
11
Later, I did this:
> int i;
> i+++(++i);
> System.out.print(i);
2
> System.out.print(i);
2
> i+++(++i);
> System.out.print(i);
4
> i+++(++i);
> System.out.print(i);
6
I concluded that the value that was being returned was the addition of i++ and another variable. But what about i+++(++i)? What's going on there? And most importantly, why would I want (or not want) to use this in my code?
i+++(++i)
We can rewrite this as
(i++) + (++i)
Note that i++ increments i and returns i's initial value, whereas ++i increments i and returns i's new value.
So, for i = 3, i++ increments i to 4 and returns 3. ++i then increments i to 5 and returns 5. Hence, the result is 8. i will have a final value of 5, as it was incremented twice:
int i = 3;
System.out.println(i+++(++i));
System.out.println(i);
8
5
Sometimes it's helpful to view this as bytecode:
ILOAD 1 // load i
IINC 1 1 // increment i
IINC 1 1 // increment i
ILOAD 1 // load new i (i.e. initial i + 2)
IADD // add top two values on stack: i and (i + 2)
And most importantly, why would I want (or not want) to use this in my code?
Never do something convoluted like this in your own code. Break it up into smaller, intelligible, parts, instead of doing it all on one line.
i+++(++i) can be re-written to (i++) + (++i)
In other words, it is the addition of a pre and post-increment of i.
However, it is so confusing and strange that it should never be used. Just use i += 2 instead.
You would never want to use this in your code. It is so confusing and obfuscated that you had to come here and ask about it. Your sense of human empathy should lead you to conclude that you would not feel good about putting another developer through that.
As for how i+++(++i), it decomposes into (i++) + (++i). If i starts as zero, the evaluation is:
i++ i becomes 1 and this evaluates to 0.
++i i becomes 2 and this evaluates to 2.
0 + 2 evaluates to 2 (not shown in your output), i is 2.
Now if i is 2:
i++ i becomes 3 and this evaluates to 2.
++i i becomes 4 and this evaluates to 4.
2 + 4 evaluates to 6 (not shown in your output), i is 4.
And if i is 4:
i++ i becomes 5 and this evaluates to 4.
++i i becomes 6 and this evaluates to 6.
4 + 6 evaluates to 10 (not shown in your output), i is 6.
Now i is 6:
i++ i becomes 7 and this evaluates to 6.
++i i becomes 8 and this evaluates to 8.
6 + 8 evaluates to 14 (not shown in your output), i is 6.
It is worth noting that a + b; is not a valid Java statement, but Dr. Java evaluates it anyways and prints the results (which it looks like you removed in your second snippet). The side effect, though, is that i is incremented twice every time (first by i++ then by ++i), as you can see by the values of i derived above.
For i+++N the decomposition is similar: This is (i++) + N. Say i is 0 and N is 3:
i++ i becomes 1 and this evaluates to 0.
0 + 3 evaluates to 3, i is 1 (not shown in your output).
Now i is 1:
i++ i becomes 2 and this evaluates to 1.
1 + 3 evaluates to 4, i is 2 (not shown in your output).
And so on. Each time, i gets incremented by 1, and the expression as a whole evaluates to the previous value of i plus N.
i+++1 => i++ post increment +1 add one, so it means: return i+1 and then increment i.
i++++x => i++ post increment, ++x pre-increment x ==> (i++)+(++x) ==> increment x, add it to i and after returning the result increment i.
Lets simplify
int x = 0;
x++ // now 1
then
x+++1 -> (x++) + 1 -> 2
I have the methods that do both the multiplication and addition, but I'm just not able to get my head around them. Both of them are from external websites and not my own:
public static void bitwiseMultiply(int n1, int n2) {
int a = n1, b = n2, result=0;
while (b != 0) // Iterate the loop till b==0
{
if ((b & 01) != 0) // Logical ANDing of the value of b with 01
{
result = result + a; // Update the result with the new value of a.
}
a <<= 1; // Left shifting the value contained in 'a' by 1.
b >>= 1; // Right shifting the value contained in 'b' by 1.
}
System.out.println(result);
}
public static void bitwiseAdd(int n1, int n2) {
int x = n1, y = n2;
int xor, and, temp;
and = x & y;
xor = x ^ y;
while (and != 0) {
and <<= 1;
temp = xor ^ and;
and &= xor;
xor = temp;
}
System.out.println(xor);
}
I tried doing a step-by-step debug, but it really didn't make much sense to me, though it works.
What I'm possibly looking for is to try and understand how this works (the mathematical basis perhaps?).
Edit: This is not homework, I'm just trying to learn bitwise operations in Java.
Let's begin by looking the multiplication code. The idea is actually pretty clever. Suppose that you have n1 and n2 written in binary. Then you can think of n1 as a sum of powers of two: n2 = c30 230 + c29 229 + ... + c1 21 + c0 20, where each ci is either 0 or 1. Then you can think of the product n1 n2 as
n1 n2 =
n1 (c30 230 + c29 229 + ... + c1 21 + c0 20) =
n1 c30 230 + n1 c29 229 + ... + n1 c1 21 + n1 c0 20
This is a bit dense, but the idea is that the product of the two numbers is given by the first number multiplied by the powers of two making up the second number, times the value of the binary digits of the second number.
The question now is whether we can compute the terms of this sum without doing any actual multiplications. In order to do so, we're going to need to be able to read the binary digits of n2. Fortunately, we can do this using shifts. In particular, suppose we start off with n2 and then just look at the last bit. That's c0. If we then shift the value down one position, then the last bit is c0, etc. More generally, after shifting the value of n2 down by i positions, the lowest bit will be ci. To read the very last bit, we can just bitwise AND the value with the number 1. This has a binary representation that's zero everywhere except the last digit. Since 0 AND n = 0 for any n, this clears all the topmost bits. Moreover, since 0 AND 1 = 0 and 1 AND 1 = 1, this operation preserves the last bit of the number.
Okay - we now know that we can read the values of ci; so what? Well, the good news is that we also can compute the values of the series n1 2i in a similar fashion. In particular, consider the sequence of values n1 << 0, n1 << 1, etc. Any time you do a left bit-shift, it's equivalent to multiplying by a power of two. This means that we now have all the components we need to compute the above sum. Here's your original source code, commented with what's going on:
public static void bitwiseMultiply(int n1, int n2) {
/* This value will hold n1 * 2^i for varying values of i. It will
* start off holding n1 * 2^0 = n1, and after each iteration will
* be updated to hold the next term in the sequence.
*/
int a = n1;
/* This value will be used to read the individual bits out of n2.
* We'll use the shifting trick to read the bits and will maintain
* the invariant that after i iterations, b is equal to n2 >> i.
*/
int b = n2;
/* This value will hold the sum of the terms so far. */
int result = 0;
/* Continuously loop over more and more bits of n2 until we've
* consumed the last of them. Since after i iterations of the
* loop b = n2 >> i, this only reaches zero once we've used up
* all the bits of the original value of n2.
*/
while (b != 0)
{
/* Using the bitwise AND trick, determine whether the ith
* bit of b is a zero or one. If it's a zero, then the
* current term in our sum is zero and we don't do anything.
* Otherwise, then we should add n1 * 2^i.
*/
if ((b & 1) != 0)
{
/* Recall that a = n1 * 2^i at this point, so we're adding
* in the next term in the sum.
*/
result = result + a;
}
/* To maintain that a = n1 * 2^i after i iterations, scale it
* by a factor of two by left shifting one position.
*/
a <<= 1;
/* To maintain that b = n2 >> i after i iterations, shift it
* one spot over.
*/
b >>>= 1;
}
System.out.println(result);
}
Hope this helps!
It looks like your problem is not java, but just calculating with binary numbers. Start of simple:
(all numbers binary:)
0 + 0 = 0 # 0 xor 0 = 0
0 + 1 = 1 # 0 xor 1 = 1
1 + 0 = 1 # 1 xor 0 = 1
1 + 1 = 10 # 1 xor 1 = 0 ( read 1 + 1 = 10 as 1 + 1 = 0 and 1 carry)
Ok... You see that you can add two one digit numbers using the xor operation. With an and you can now find out whether you have a "carry" bit, which is very similar to adding numbers with pen&paper. (Up to this point you have something called a Half-Adder). When you add the next two bits, then you also need to add the carry bit to those two digits. Taking this into account you can get a Full-Adder. You can read about the concepts of Half-Adders and Full-Adders on Wikipedia:
http://en.wikipedia.org/wiki/Adder_(electronics)
And many more places on the web.
I hope that gives you a start.
With multiplication it is very similar by the way. Just remember how you did multiplying with pen&paper in elementary school. Thats what is happening here. Just that it's happening with binary numbers and not with decimal numbers.
EXPLANATION OF THE bitwiseAdd METHOD:
I know this question was asked a while back but since no complete answer has been given regarding how the bitwiseAdd method works here is one.
The key to understanding the logic encapsulated in bitwiseAdd is found in the relationship between addition operations and xor and and bitwise operations. That relationship is defined by the following equation (see appendix 1 for a numeric example of this equation):
x + y = 2 * (x&y)+(x^y) (1.1)
Or more simply:
x + y = 2 * and + xor (1.2)
with
and = x & y
xor = x ^ y
You might have noticed something familiar in this equation: the and and xor variables are the same as those defined at the beginning of bitwiseAdd. There is also a multiplication by two, which in bitwiseAdd is done at the beginning of the while loop. But I will come back to that later.
Let me also make a quick side note about the '&' bitwise operator before we proceed further. This operator basically "captures" the intersection of the bit sequences against which it is applied. For example, 9 & 13 = 1001 & 1101 = 1001 (=9). You can see from this result that only those bits common to both bit sequences are copied to the result. It derives from this that when two bit sequences have no common bit, the result of applying '&' on them yields 0. This has an important consequence on the addition-bitwise relationship which shall become clear soon
Now the problem we have is that equation 1.2 uses the '+' operator whereas bitwiseAdd doesn't (it only uses '^', '&' and '<<'). So how do we make the '+' in equation 1.2 somehow disappear? Answer: by 'forcing' the and expression to return 0. And the way we do that is by using recursion.
To demonstrate this I am going to recurse equation 1.2 one time (this step might be a bit challenging at first but if needed there's a detailed step by step result in appendix 2):
x + y = 2*(2*and & xor) + (2*and ^ xor) (1.3)
Or more simply:
x + y = 2 * and[1] + xor[1] (1.4)
with
and[1] = 2*and & xor,
xor[1] = 2*and ^ xor,
[1] meaning 'recursed one time'
There's a couple of interesting things to note here. First you noticed how the concept of recursion sounds close to that of a loop, like the one found in bitwiseAdd in fact. This connection becomes even more obvious when you consider what and[1] and xor[1] are: they are the same expressions as the and and xor expressions defined INSIDE the while loop in bitwiseAdd. We also note that a pattern emerges: equation 1.4 looks exactly like equation 1.2!
As a result of this, doing further recursions is a breeze, if one keeps the recursive notation. Here we recurse equation 1.2 two more times:
x + y = 2 * and[2] + xor[2]
x + y = 2 * and[3] + xor[3]
This should now highlight the role of the 'temp' variable found in bitwiseAdd: temp allows to pass from one recursion level to the next.
We also notice the multiplication by two in all those equations. As mentioned earlier this multiplication is done at the begin of the while loop in bitwiseAdd using the and <<= 1 statement. This multiplication has a consequence on the next recursion stage since the bits in and[i] are different from those in the and[i] of the previous stage (and if you recall the little side note I made earlier about the '&' operator you probably see where this is going now).
The general form of equation 1.4 now becomes:
x + y = 2 * and[x] + xor[x] (1.5)
with x the nth recursion
FINALY:
So when does this recursion business end exactly?
Answer: it ends when the intersection between the two bit sequences in the and[x] expression of equation 1.5 returns 0. The equivalent of this in bitwiseAdd happens when the while loop condition becomes false. At this point equation 1.5 becomes:
x + y = xor[x] (1.6)
And that explains why in bitwiseAdd we only return xor at the end!
And we are done! A pretty clever piece of code this bitwiseAdd I must say :)
I hope this helped
APPENDIX:
1) A numeric example of equation 1.1
equation 1.1 says:
x + y = 2(x&y)+(x^y) (1.1)
To verify this statement one can take a simple example, say adding 9 and 13 together. The steps are shown below (the bitwise representations are in parenthesis):
We have
x = 9 (1001)
y = 13 (1101)
And
x + y = 9 + 13 = 22
x & y = 9 & 13 = 9 (1001 & 1101 = 1001)
x ^ y = 9^13 = 4 (1001 ^ 1101 = 0100)
pluging that back into equation 1.1 we find:
9 + 13 = 2 * 9 + 4 = 22 et voila!
2) Demonstrating the first recursion step
The first recursion equation in the presentation (equation 1.3) says that
if
x + y = 2 * and + xor (equation 1.2)
then
x + y = 2*(2*and & xor) + (2*and ^ xor) (equation 1.3)
To get to this result, we simply took the 2* and + xor part of equation 1.2 above and applied the addition/bitwise operands relationship given by equation 1.1 to it. This is demonstrated as follow:
if
x + y = 2(x&y) + (x^y) (equation 1.1)
then
[2(x&y)] + (x^y) = 2 ([2(x&y)] & (x^y)) + ([2(x&y)] ^ (x^y))
(left side of equation 1.1) (after applying the addition/bitwise operands relationship)
Simplifying this with the definitions of the and and xor variables of equation 1.2 gives equation 1.3's result:
[2(x&y)] + (x^y) = 2*(2*and & xor) + (2*and ^ xor)
with
and = x&y
xor = x^y
And using that same simplification gives equation 1.4's result:
2*(2*and & xor) + (2*and ^ xor) = 2*and[1] + xor[1]
with
and[1] = 2*and & xor
xor[1] = 2*and ^ xor
[1] meaning 'recursed one time'
Here is another approach for Multiplication
/**
* Multiplication of binary numbers without using '*' operator
* uses bitwise Shifting/Anding
*
* #param n1
* #param n2
*/
public static void multiply(int n1, int n2) {
int temp, i = 0, result = 0;
while (n2 != 0) {
if ((n2 & 1) == 1) {
temp = n1;
// result += (temp>>=(1/i)); // To do it only using Right shift
result += (temp<<=i); // Left shift (temp * 2^i)
}
n2 >>= 1; // Right shift n2 by 1.
i++;
}
System.out.println(result);
}
How can you write the following statement in the given languages?
a(0) = 1
a_(n+1) = 1 - 1 / ( a_n + 3)
I need to find the smallest value of n when a_n -> 0.732050....
My attempt in Mathematica
a[(x+1)_] = 1 - 1/(a[x_] + 3)
The problem is apparently in this a[(x+1)_].
However, I do not know how to do it iteratively in Mathematica.
Mathematica
a[0] = 1;
a[n_] := a[n] = 1 - 1/(a[n-1] + 3)
(Note the memoization trick.)
Also, a[n] converges (very quickly) to sqrt(3)-1:
Solve[x == 1 - 1/(x+3), x]
Python, simplest:
def a(n):
if n == 0: return 1
return 1 - 1 / float(a(n-1) + 3)
# limit is sqrt(3) - 1
limit = 3.0 ** 0.5 - 1.0
# get 9 digits' precision
i = 0
while abs(a(i) - limit) > 1.0e-9:
i += 1
print i
This emits 8, suggesting that optimizations such as recursion elimination or memoizing are likely not warranted.
Of course normally we'd want to get the limit numerically rather than analytically, so the normal way to loop would be rather different -- and best encapsulated in a higher-order function...:
# get a function's limit numerically
def limit(f, eps=1.0e-11):
previous_value = f(0)
next_value = f(1)
i = 2
while abs(next_value - previous_value) > eps:
previous_value = next_value
next_value = f(i)
i += 1
return next_value
Nontrivial looping logic is usually best encapsulated in a generator:
def next_prev(f):
previous_value = f(0)
i = 1
while True:
next_value = f(i)
yield next_value, previous_value
i += 1
previous_value = next_value
with the help of this generator, the limit HOF becomes much simpler:
def limit(f, eps=1.0e-11):
for next_value, previous_value in next_prev(f):
if abs(next_value - previous_value) < eps:
return next_value
Note how useful the separation is: next_prev embodies the concept of "get the next and previous value of the function", limit just deals with "when should the loop terminate".
Last but not least, itertools often offers a good alternative to generators, letting you encapsulate finicky iteration logic in speedy ways (though it does take some getting used to...;-):
import itertools
def next_prev(f):
values = itertools.imap(f, itertools.count())
prv, nxt = itertools.tee(values)
nxt.next()
return itertools.izip(prv, nxt)
Java
double A = 1;
int n = 0;
while (true) {
System.out.println(n + " " + A);
A = 1 - 1 / (A + 3);
n++;
}
Python
A = 1.0
n = 0
while 1:
print n, A
A = 1 - 1 / (A + 3)
n += 1
Mathematica:
a[0] := 1
a[k_] := 1 - 1/(a[k - 1] + 3)
I substituted k = n + 1 because that makes the expression simpler. The result is equivalent.
Python
next = lambda x: 1.0 - (1.0 / (float(x) + 3.0))
last, z, count = -1, 0.0, 0
while last != z:
print count, z
last, z, count = z, next(z), count+1
I try to avoid writing "while True" or such if I can avoid it. Almost certainly no code that I write will loop forever. In this case, it ran sixteen times for me. Sixteen is a lot less than ℵ-null.
A one-liner in Mathematica which gives a list of exact elements of your sequence:
In[66]:= NestWhileList[1 - 1/(#1 + 3) &, 1,
RealExponent[Subtract[##]] > -8 &, 2]
Out[66]= {1, 3/4, 11/15, 41/56, 153/209, 571/780, 2131/2911, \
7953/10864, 29681/40545}
The difference between the last two elements is less than 10^-8. It thus have taken 8 iterations:
In[67]:= Length[%]
Out[67]= 9