calculation with increment operators - java

Java says that the result of the following calculation is -24.
But isn't --(-3)*(6)++ == -4*7 == -28?
public int rechnung3()
{
int k = -3;
int i = 6;
return --k*i++;
}

No because the postfix increment happens after the expression has been evaluated. So essentially, the i is only incremented after the result has been stored on the stack.
So what happens is equivalent to something like this:
int k = -3;
int i = 6;
k = k -1; // --k makes k = -4
int tmp = k * i; // a temporary location stores the value of (--k) * i = -24
i = i + 1; // i++ increments i, now i = 7
return tmp; // returns -24 (the result from the auxiliary location)

Your variable k has the "pre-decrement" operator, meaning that the value is reduced before it is used in the calculation. So your -4 is correct. However, the variable i has the "post-increment" operator, meaning that the value is increased after it is used in the calculation. So, the value that is used is 6. If there were any code later in the function (if you did not return immediately), the value would be 7 if you used the variable again.

Related

Hashing to Negative Values

Pretty much the title: I'm hashing a bunch of names (10000-ish) and some are outputting as negative. (table size is 20011).
The hash function in question is:
public static long hash2 ( String key ){
int hashVal = 0;
for( int i = 0; i < key.length(); i++ )
hashVal = (37 * hashVal) + key.charAt(i);
return hashVal % 20011;
}
I dug around and I think I have to do something to do with "wrap around." But I don't know how to go about that.
This is a clear case of Integer Overflow. As you have mentioned in the question that the String may have upto 10000 characters then the hashValue will definitely overflow because it is needed to store value around 37^10000. Even this will fail in string of length 20.
In number theory,
(A+B)%M = (A%M + B%M) % M;
(A*B)%M = (A%M * B%M) % M;
You should apply modulo operation inside the for loop. However If you do modulo operation at last or in execution of for loop, Both will give the same answer If overflow doesn't happen.
So make changes accordingly,
public static long hash2 ( String key ){
int hashVal = 0;
for( int i = 0; i < key.length(); i++ )
{
hashVal = (37 * hashVal) + key.charAt(i);
hashVal%=20011;
}
return hashVal;
}
hashVal is an Integer. It is most likely that your hash function is causing an Integer overflow.
You can easily resolve this by using Math.abs() to ensure that hashVal is a positive number. e.g.
hashVal = hashVal == Integer.MIN_VALUE ? 0 : Math.abs(hashVal);
return hashVal % 20011;
The mod % is to ensure that the final index computed is within the bounds of the table (i.e. if it's >= 20011, it uses the the remainder of division to as you say 'wrap around').

Why is the result not 1? [duplicate]

This question already has answers here:
What is x after "x = x++"?
(18 answers)
If y = 1 and y = y++, why when I print y is the value 1? [duplicate]
Closed 9 years ago.
int m = 0;
m += m++;
System.out.println(m);
prints to 0
but i thought m will be post incremented and finally be 1.
Would someone please explain.
Note: i know how post increment works (atleast i think i do :P). But what i am trying to figure out is that when i say m + = m++ lets assume it means m = m + m++ which will evaluate m++ after sending the value of m, 0 in this case, and evaluate to m = 0 + 0 then increment the value of m because of the post increment. now if post increment has occured, why is m not 1
m++ returns m then increments it.
Change it to ++m and you'll see 1.
For clarity, this question explains it too: What is x after "x = x++"?
Consider the following rules:
a += b is equivalent to a = a + b. Therefore m += m++ is equivalent to m = m + m++.
You can see that the first occurence of m at the right sight is evaluated before the increment and produces 0
m++ increments m and returns original value of m before the increment.
So, in your case m++ sets m to 1 and returns 0
Assignment happens after evaluation of the right side, whereas post-increment happens during evaluation of the right side.
Now you can see that your expression is evaluated as follows:
Evaluation of the right side produces 0 and sets m to 1
Assignment sets m to value of the right side (0)
The sequence of events is:
The RHS is evaluated (0)
The post increment is done (m++).
The evaluated result is assigned (m=0 again).
i.e. this is equivalent to:
tmp = m;
m++;
m = tmp;
If you did m = ++m, the sequence would be:
The pre increment is done (++m).
The RHS is evaluated (1)
The evaluated result is assigned (m=1).
ANSWER: An assignment evaluates side effects before performing the assignment.
m += m++;
is equivalent to
temp = m + m++; ; m is now 1, but temp is 0
m = temp; ; m is now 0 again
int m = 0
At this point m is 0
m += m++;
Expands to m=m+(m++)
m returns 0
m++ returns the value of m which is 0 and then increments it to 1
transforming m+(m++) into 0+0 (m is 1 a this point)
This is then assigned to m resulting in the final value of m.
Tip: avoid post-increment when you're touching the value otherwise
In your code
m+ =m++; Results -- >> M value + (post incremented m value(m++))
Initially
m value= 0
post incremented(m++) m value = 0 (pre increment(++m) = 1)
Well m++ return the value of m before to increment it, contrary to ++m that increment then return, like:
int m++(int m){
int tmp = m;
m = m+1;
return tmp;
}
int ++m(int m){
m = m+1;
return m;
}
f is your code. g is an expanded version showing why they both print 0.
class Test {
private static void f() {
int x = 0;
x += x++;
System.out.println(x);
}
private static void g() {
int x = 0;
int preInc = x; // preInc = 0
x += 1; // x = 1
x = preInc; // x = 0
System.out.println(x);
}
public static void main(String[] args) {
f();
g();
}
}

Why doesn't the post increment operator work on a method that returns an int?

public void increment(){
int zero = 0;
int oneA = zero++; // Compiles
int oneB = 0++; // Doesn't compile
int oneC = getInt()++; // Doesn't compile
}
private int getInt(){
return 0;
}
They are all int's, why won't B & C compile? Is it to do with the way ++ operator differs from = 0 + 1;?
Invalid argument to operation ++/--
i++ is an assignment to a variable i.
In your case, zero++ is an equivalent to zero = zero + 1. So 0++ would mean 0 = 0 + 1, which makes no sense, as well as getInt() = getInt() + 1.
More accurately :
int oneA = zero++;
means
int oneA = zero;
zero = zero + 1; // OK, oneA == 0, zero == 1
int oneB = 0++;
means
int oneB = 0;
0 = 0 + 1; // wrong, can't assign value to a value.
int oneC = getInt()++;
means
int oneC = getInt();
getInt() = getInt() + 1; // wrong, can't assign value to a method return value.
From a more general point of view, a variable is a L-value, meaning that it refers to a memory location, and can therefore be assigned. L in L-value stands for left side of the assignment operator (i.e. =), even if L-values can be found either on the left side or the right side of the assignment operator (x = y for instance).
The opposite is R-value (R stands for right side of the assignment operator). R-values can be used only on the right side of assignment statements, to assign something to a L-value. Typically, R-values are literals (numbers, characters strings...) and methods.
Because as stated in JLS:
The result of the postfix expression must be a variable of a type that
is convertible (§5.1.8) to a numeric type, or a compile-time error
occurs.
getInt() is not int
getInt() returns int
++ operator does two things increment + assignment
So for ++ operator to work you need a variable to store the result of increment operation which 0 and getInt() both are not.
The pre- and post- operators only operate on variables or lvalues as they are called. lvalue is short for left value, i.e. something that can stand to the left in an assignment.
In your example:
zero = 1; // OK
0 = 1; // Meaningless
getInt() = 1; // Also meaningless
//jk
Both B and C make the compiler say:
unexpected type, required: variable, found: value
So you can't increment a value, only a variable.
Why doesn't the post increment operator work on a method that returns an int?
Because it is a getter method, and it doesn't make sense to change a value via getter.
int z = x + y++;
is equivalent to:
int z = x + y;
y = y + 1;
so it is not valid to have something like:
int z = x + getY()++;
which is equivalent to:
int z = x + getY();
getY() = getY() + 1; // invalid!
0++
It is equivalent to 0 = 0 + 1; and certainly it is not possible.
i.e. it has to be l-value to assign to it.
getInt()++;
Similar reason here.
Because 0 is a rValue (i.e. You can use it only from right of the assignment operator) not a lValue.
++ operator increments the value and sets it to itself therefore 0++ will give You an error.
My answer its kind of "out of the box".
When I have doubt about an operator usage, I think "which its the overloaded function equivalent" of this operator ?
I, know, that Java operators doesn't have operator overloading, its just an alternative way to make a solution.
In this case:
...
x++;
...
should be read as:
...
int /* function */ postincrement (/* ref */ int avalue)
{
int Result = avalue;
// reference value,
avalue = avalue + 1;
return Result;
}
...
postincrement(/* ref */ x);
...
And:
...
++x;
...
...
int /* function */ preincrement (/* ref */ int avalue)
{
// reference value,
avalue = avalue + 1;
int Result = avalue;
return Result;
}
...
preincrement(/* ref */ x);
...
So, both, versions of "++", work as a function that receives a variable parameter by reference.
So, a literal value like "0++" or a function result like "getInt()++", are not a variable references.
Cheers.
postincrement and preincrement can apply only with the help of variable.So the first case compile.
Since function return is RHS expression and pre/post increment/decrement operations can be applied to LHS expressions only.

Strange double rounding issue

I came across the following silly function here:
public static String findOutWhatLifeIsAllAbout() {
int meaning = 0;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 20; j++) {
for (int k = 0; k < 300; k++) {
for (int m = 0; m < 7000; m++) {
meaning += Math.random() + 1;
}
}
}
}
return String.valueOf(meaning).replaceAll("0*$", "");
}
In summary, the expected result is a string "42", since Math.random() returns doubles "greater than or equal to 0.0 and less than 1.0". In practice, running on an i5 under Ubuntu the resulting strings are similar to "420000011", "420000008"! (meaning sometimes Math.random()'s result is getting rounded up!
To get a grip on what sorts of double values would cause Math.random()'s result to somehow round to 1, I tried this function instead, expecting to see some examples.
public static String findOutWhatLifeIsAllAboutAltered() {
int meaning = 0;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 20; j++) {
for (int k = 0; k < 300; k++) {
for (int m = 0; m < 7000; m++) {
double randomResult = Math.random();
int converted = randomResult;
if (converted > 0) {
System.out.println("Misbehaving double = " + randomResult);
}
meaning += converted + 1;
}
}
}
}
return String.valueOf(meaning).replaceAll("0*$", "");
}
However this formulation always returns "42"! Can anyone offer insight about why the behavior changes in the altered function? Thanks.
Furthermore why does Java let the original function compile at all? Shouldn't there be a loss-of-precision error at the += call?
edit posted the code I wanted you all to see - the "original" version wasn't supposed to have a cast.
There's a small but important difference between the code in the link and the code originally posted here,
meaning += Math.random() + 1; // link
vs.
meaning += (int)Math.random() + 1; // StackOverflow
If the code posted here prints out anything but 42, it's a serious bug.
Here, the result of Math.random() is explicitly cast to int, that must result in 0, then 1 is added, resulting in 1, which then is added to meaning.
The code in the linked post, however performs an implicit cast to int after adding the result of Math.random() to 1 and that to meaning, basically
meaning = (int)(Math.random() + (double)1 + (double)meaning);
Now, if the result of Math.random() is close enough to 1.0, it occasionally happens that the result of the double addition is rounded up, so producing a final result slightly larger than immediately expected.
Shouldn't there be a loss-of-precision error at the += call?
No. In the first case, you're explicitly casting the value returned by Math.random() to an int. In the second case, meaning, converted, and 1 are all integers.
There is, however, a possible loss-of-precision at this line:
int converted = randomResult;
http://ideone.com/1ZTDi
There won't be a loss of precision error at all because they're all ints in this example - you're not actually adding any doubles!
The only line where you could be you're casting the result of Math.random() to an int - so you're still just adding two ints together.
However, even if you were adding doubles to an int then there still wouldn't be because the JLS defines an implicit cast for these types of operators:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
Source:
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.26.2
Loss of precision could only come on these lines as you're doing type conversion:
double randomResult = Math.random();
int converted = randomResult;
As Math.random() returns an double which is between 0.0 inclusive and 1.0 exclusive, the variable converted will only ever contain 0 as it's converted to an int.
For more on the casting from a double > int, see here: Different answer when converting a Double to an Int - Java vs .Net
I've tried your original program on a Java 6 system running on Mac OS X (Lion) and it only outputs 42. Which JRE/JDK are you using?

Is there a difference between x++ and ++x in java?

Is there a difference between ++x and x++ in java?
++x is called preincrement while x++ is called postincrement.
int x = 5, y = 5;
System.out.println(++x); // outputs 6
System.out.println(x); // outputs 6
System.out.println(y++); // outputs 5
System.out.println(y); // outputs 6
yes
++x increments the value of x and then returns x
x++ returns the value of x and then increments
example:
x=0;
a=++x;
b=x++;
after the code is run both a and b will be 1 but x will be 2.
These are known as postfix and prefix operators. Both will add 1 to the variable but there is a difference in the result of the statement.
int x = 0;
int y = 0;
y = ++x; // result: x=1, y=1
int x = 0;
int y = 0;
y = x++; // result: x=1, y=0
Yes,
int x=5;
System.out.println(++x);
will print 6 and
int x=5;
System.out.println(x++);
will print 5.
In Java there is a difference between x++ and ++x
++x is a prefix form:
It increments the variables expression then uses the new value in the expression.
For example if used in code:
int x = 3;
int y = ++x;
//Using ++x in the above is a two step operation.
//The first operation is to increment x, so x = 1 + 3 = 4
//The second operation is y = x so y = 4
System.out.println(y); //It will print out '4'
System.out.println(x); //It will print out '4'
x++ is a postfix form:
The variables value is first used in the expression and then it is incremented after the operation.
For example if used in code:
int x = 3;
int y = x++;
//Using x++ in the above is a two step operation.
//The first operation is y = x so y = 3
//The second operation is to increment x, so x = 1 + 3 = 4
System.out.println(y); //It will print out '3'
System.out.println(x); //It will print out '4'
Hope this is clear. Running and playing with the above code should help your understanding.
I landed here from one of its recent dup's, and though this question is more than answered, I couldn't help decompiling the code and adding "yet another answer" :-)
To be accurate (and probably, a bit pedantic),
int y = 2;
y = y++;
is compiled into:
int y = 2;
int tmp = y;
y = y+1;
y = tmp;
If you javac this Y.java class:
public class Y {
public static void main(String []args) {
int y = 2;
y = y++;
}
}
and javap -c Y, you get the following jvm code (I have allowed me to comment the main method with the help of the Java Virtual Machine Specification):
public class Y extends java.lang.Object{
public Y();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_2 // Push int constant `2` onto the operand stack.
1: istore_1 // Pop the value on top of the operand stack (`2`) and set the
// value of the local variable at index `1` (`y`) to this value.
2: iload_1 // Push the value (`2`) of the local variable at index `1` (`y`)
// onto the operand stack
3: iinc 1, 1 // Sign-extend the constant value `1` to an int, and increment
// by this amount the local variable at index `1` (`y`)
6: istore_1 // Pop the value on top of the operand stack (`2`) and set the
// value of the local variable at index `1` (`y`) to this value.
7: return
}
Thus, we finally have:
0,1: y=2
2: tmp=y
3: y=y+1
6: y=tmp
When considering what the computer actually does...
++x: load x from memory, increment, use, store back to memory.
x++: load x from memory, use, increment, store back to memory.
Consider:
a = 0
x = f(a++)
y = f(++a)
where function f(p) returns p + 1
x will be 1 (or 2)
y will be 2 (or 1)
And therein lies the problem. Did the author of the compiler pass the parameter after retrieval, after use, or after storage.
Generally, just use x = x + 1. It's way simpler.
Yes.
public class IncrementTest extends TestCase {
public void testPreIncrement() throws Exception {
int i = 0;
int j = i++;
assertEquals(0, j);
assertEquals(1, i);
}
public void testPostIncrement() throws Exception {
int i = 0;
int j = ++i;
assertEquals(1, j);
assertEquals(1, i);
}
}
Yes, using ++X, X+1 will be used in the expression. Using X++, X will be used in the expression and X will only be increased after the expression has been evaluated.
So if X = 9, using ++X, the value 10 will be used, else, the value 9.
If it's like many other languages you may want to have a simple try:
i = 0;
if (0 == i++) // if true, increment happened after equality check
if (2 == ++i) // if true, increment happened before equality check
If the above doesn't happen like that, they may be equivalent
Yes, the value returned is the value after and before the incrementation, respectively.
class Foo {
public static void main(String args[]) {
int x = 1;
int a = x++;
System.out.println("a is now " + a);
x = 1;
a = ++x;
System.out.println("a is now " + a);
}
}
$ java Foo
a is now 1
a is now 2
OK, I landed here because I recently came across the same issue when checking the classic stack implementation. Just a reminder that this is used in the array based implementation of Stack, which is a bit faster than the linked-list one.
Code below, check the push and pop func.
public class FixedCapacityStackOfStrings
{
private String[] s;
private int N=0;
public FixedCapacityStackOfStrings(int capacity)
{ s = new String[capacity];}
public boolean isEmpty()
{ return N == 0;}
public void push(String item)
{ s[N++] = item; }
public String pop()
{
String item = s[--N];
s[N] = null;
return item;
}
}
Yes, there is a difference, incase of x++(postincrement), value of x will be used in the expression and x will be incremented by 1 after the expression has been evaluated, on the other hand ++x(preincrement), x+1 will be used in the expression.
Take an example:
public static void main(String args[])
{
int i , j , k = 0;
j = k++; // Value of j is 0
i = ++j; // Value of i becomes 1
k = i++; // Value of k is 1
System.out.println(k);
}
The Question is already answered, but allow me to add from my side too.
First of all ++ means increment by one and -- means decrement by one.
Now x++ means Increment x after this line and ++x means Increment x before this line.
Check this Example
class Example {
public static void main (String args[]) {
int x=17,a,b;
a=x++;
b=++x;
System.out.println(“x=” + x +“a=” +a);
System.out.println(“x=” + x + “b=” +b);
a = x--;
b = --x;
System.out.println(“x=” + x + “a=” +a);
System.out.println(“x=” + x + “b=” +b);
}
}
It will give the following output:
x=19 a=17
x=19 b=19
x=18 a=19
x=17 b=17
public static void main(String[] args) {
int a = 1;
int b = a++; // this means b = whatever value a has but, I want to
increment a by 1
System.out.println("a is --> " + a); //2
System.out.println("b is --> " + b); //1
a = 1;
b = ++a; // this means b = a+1
System.out.println("now a is still --> " + a); //2
System.out.println("but b is --> " + b); //2
}
With i++, it's called postincrement, and the value is used in whatever context then incremented; ++i is preincrement increments the value first and then uses it in context.
If you're not using it in any context, it doesn't matter what you use, but postincrement is used by convention.
There is a huge difference.
As most of the answers have already pointed out the theory, I would like to point out an easy example:
int x = 1;
//would print 1 as first statement will x = x and then x will increase
int x = x++;
System.out.println(x);
Now let's see ++x:
int x = 1;
//would print 2 as first statement will increment x and then x will be stored
int x = ++x;
System.out.println(x);
Try to look at it this way:
from left to right do what you encounter first. If you see the x first, then that value is going to be used in evaluating the currently processing expression, if you see the increment (++) first, then add one to the current value of the variable and continue with the evaluation of the expression. Simple

Categories