Can you please help me understand what the following code means:
x += 0.1;
The "common knowledge" of programming is that x += y is an equivalent shorthand notation of x = x + y. As long as x and y are of the same type (for example, both are ints), you may consider the two statements equivalent.
However, in Java, x += y is not identical to x = x + y in general.
If x and y are of different types, the behavior of the two statements differs due to the rules of the language. For example, let's have x == 0 (int) and y == 1.1 (double):
int x = 0;
x += 1.1; // just fine; hidden cast, x == 1 after assignment
x = x + 1.1; // won't compile! 'cannot convert from double to int'
+= performs an implicit cast, whereas for + you need to explicitly cast the second operand, otherwise you'd get a compiler error.
Quote from Joshua Bloch's Java Puzzlers:
(...) compound assignment expressions automatically cast the result of
the computation they perform to the type of the variable on their
left-hand side. If the type of the result is identical to the type of
the variable, the cast has no effect. If, however, the type of the
result is wider than that of the variable, the compound
assignment operator performs a silent narrowing primitive
conversion [JLS 5.1.3].
x += y is x = x + y
x -= y is x = x - y
x *= y is x = x * y
x /= y is x = x / y
x %= y is x = x % y
x ^= y is x = x ^ y
x &= y is x = x & y
x |= y is x = x | y
and so on ...
It's one of the assignment operators. It takes the value of x, adds 0.1 to it, and then stores the result of (x + 0.1) back into x.
So:
double x = 1.3;
x += 0.1; // sets 'x' to 1.4
It's functionally identical to, but shorter than:
double x = 1.3;
x = x + 0.1;
NOTE: When doing floating-point math, things don't always work the way you think they will.
devtop += Math.pow(x[i] - mean, 2); will add the result of the operation Math.pow(x[i] - mean, 2) to the devtop variable.
A more simple example:
int devtop = 2;
devtop += 3; // devtop now equals 5
In java the default type of numbers like 2 or -2(without a fractional component) is int and unlike c# that's not an object and we can't do sth like 2.tostring as in c# and the default type of numbers like 2.5(with a fractional component) is double;
So if you write:
short s = 2;
s = s + 4;
you will get a compilation error that int cannot be cast into short also if you do sth like below:
float f = 4.6;
f = f + 4.3;
you will get two compilation errors for setting double '4.6' to a float variable at both lines and the error of first line is logical because float and double use different system of storing numbers and using one instead of another can cause data loss;
two examples mentioned can be changed like this:
s += 4
f += 4.3
which both have an implicit cast behind code and have no compile errors;
Another point worthy of consideration is numbers in the range of 'byte' data type are cached in java and thus numbers -128 to 127 are of type byte in java and so this code doesn't have any compile errors:
byte b = 127
but this one has an error indeed:
byte b = 128
because 128 is an int in java;
about long numbers we are recommended to use an L after the number for the matter of integer overflow like this:
long l = 2134324235234235L
in java we don't have operator overloading like c++ but += is overloaded only for String and not for the let's say StringBuilder or StringBuffer and we can use it instead of String 'concat' method but as we know String is immutable and that will make another object and will not change the same object as before :
String str = "Hello";
str += "World";
It's fine;
You can take a look at the bytecode whenever you want to understand how java operators work. Here if you compile:
int x = 0;
x += 0.1;
the bytecode will be accessible with jdk command javap -c [*.class]:(you can refer to Java bytecode instruction listings for more explanation about bytecode)
0: iconst_0 // load the int value 0 onto the stack
1: istore_1 // store int value into variable 1 (x)
2: iload_1 // load an int value from local variable 1 (x)
3: i2d // convert an int into a double (cast x to double)
4: ldc2_w #2 // double 0.1d -> push a constant value (0.1) from a constant pool onto the stack
7: dadd // add two doubles (pops two doubles from stack, adds them, and pushes the answer onto stack)
8: d2i // convert a double to an int (pops a value from stack, casts it to int and pushes it onto stack)
9: istore_1 // store int value into variable 1 (x)
Now it is clear that java compiler promotes x to double and then adds it with 0.1.
Finally it casts the answer to integer .
There is one interesting fact I found out that when you write:
byte b = 10;
b += 0.1;
compiler casts b to double, adds it with 0.1, casts the result which is double to integer, and finally casts it to byte and that is because there is no instruction to cast double to byte directly.
You can check the bytecode if you doubt :)
devtop += Math.pow(x[i] - mean, 2); adds Math.pow(x[i] - mean, 2) to devtop.
It increases the value of the variable by the the value after +=.
For example:
float x = 0;
x += 0.1;
//x is now 0.1
x += 0.1;
//x is now 0.2
It's just a shorter version of:
x = x+0.1;
Related
I want to convert a double value to int when and only when 2 numbers after the dot are 0.
Example
double x = 25.001
You can use this :
double x = 25.001;
int i = (int) x;
System.out.println(x);//Input
if (x - i <= 0.01) {
x = (int) x;
}
System.out.println(x);//Output
RESULT
Input Output
25.001 25.0
25.011 25.011
If you want to use a second variable you can use :
int y = 0;
if (x - i <= 0.01) {
y = (int) x;
}
Note
But note, in case your input is not correct, you will always get 0, i like the first solution it is good then the second.
if(x-Integer.parseInt(x)>=0.001)
//Convert here
That rounded number you then cannot store in a double, as a double is always an approximation of a real value - of a series of a (negative) power of 2.
So you should go for BigDecimal as many do that want to do financial software.
If you did something like:
double adjustWhenCloseToInt(double x) {
long n = Math.round(x); // Could overflow for large doubles
if (Math.abs(x - n) < 0.01) {
x = n;
}
return x;
}
A simple
x = adjustWhenCloseToInt(x);
System.out.print(x);
Could still print 0.00000001 or such.
The solution there is
System.out.printf("%.2f", x);
Or better use a localized MessageFormat (thousand separators and such).
As floating point always bears rounding errors, I would in general go for BigDecimal, though it is a circumstantial class to use. Take care to use String constructors:
new BigDecimal("3.99");
As they then can maintain a precision of 2.
For example:
int a = 10;
a += 1.5;
This runs perfectly, but
a = a+1.5;
this assignment says Type mismatch: cannot convert from double to int.
So my question is: what is the difference between += operator and = operator. Why the first assignment didn't says nothing, but second will. Please explain to me. Just I want to know whether I can use the first assignment to all place or not.
From the Java Language Specification section 15.26.2:
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.
So the most important difference (in terms of why the second version doesn't compile) is the implicit cast back to the type of the original variable.
int a = 10;
a += 1.5;
is equivalent to:
int a = 10;
a = (int) (a + 1.5);
In general:
x += y; is equivalent to x = (type of x) (x + y);
See 15.26.2. Compound Assignment Operators
Check this link
int a = 10;
a += 1.5;
will be treated as
int a=10;
a=(int)(a+1.5);
As you can found in this link expressions
In case of
a += 1.5;
implicit auto boxing is done
where as here
a = a+1.5;
you are explicitly adding a int variable to a float/double variable
so to correct it
a = a+(int)1.5;
or
a = (int) (a+1.5);
Hi I'm trying to run a calculation but I can't seem to put it all on one line, I have to split the result into two seperate lines to achieve the desired result (which seems a bit long winded).
Can anyone explain where I'm going wrong?
both x and y are doubles.
Example 1: (incorrect)
y=0.68
x= (Math.round(y* 10))/10;
result x=0
Example 2: (correct)
y=0.68
x= Math.round(y* 10);
x = x/10;
result x=0.7
thanks for your time.
Math.round returns variable of type long (see: Javadoc), which means that the division by 10 is performed on a long variable resulting in another long variable - that's why you lose the precision.
To make it calculate on it as on double and return double - you have to cast the result of Math.round like this:
x= ((double)Math.round(y* 10))/10;
Have you tried to explicitly specify double in your calculation:
x = ((double)Math.round( y * 10.0)) / 10.0;
Math.round returns a long....
It's hard to tell from your snippets, because they don't include variable types, but it's likely to be integer division that's killing you. When you divide two integers x and y, where x < y, you get zero:
int x = 4;
int y = 10;
int z = x/y; // this is zero.
y=0.68
x= (Math.round(y* 10)) <--- Evaluated as int since Math.round returns int /10; <-- integer division
result x=0
y=0.68
x= Math.round(y* 10) <-- x is stored as double
x = x/10; <-- double division
result x=7
I guess it's because Math.round returns either a long or an int, depending on whether y is double or float. an then you have an integer division.
in the second example x is already a double and that's why you have a double division.
When you write:
double x = (Math.round(y* 10))/10;
(Math.round(y* 10)) is a long (= 7), which you divide by 10, that gives another long (= 0). The result is then converted back to a double and stored in x.
In your second snippet:
double x = Math.round(y* 10);
This is equal to 7 and converted into a double. x / 10 is then a double operation that returns 0.7.
I've misplaced += with =+ one too many times, and I think I keep forgetting because I don't know the difference between these two, only that one gives me the value I expect it to, and the other does not.
Why is this?
a += b is short-hand for a = a + b (though note that the expression a will only be evaluated once.)
a =+ b is a = (+b), i.e. assigning the unary + of b to a.
Examples:
int a = 15;
int b = -5;
a += b; // a is now 10
a =+ b; // a is now -5
+= is a compound assignment operator - it adds the RHS operand to the existing value of the LHS operand.
=+ is just the assignment operator followed by the unary + operator. It sets the value of the LHS operand to the value of the RHS operand:
int x = 10;
x += 10; // x = x + 10; i.e. x = 20
x =+ 5; // Equivalent to x = +5, so x = 5.
+= → Add the right side to the left
=+ → Don't use this. Set the left to the right side.
a += b equals a = a + b. a =+ b equals a = (+b).
x += y
is the same as
x = x + y
and
x =+ y
is wrong but could be interpreted as
x = 0 + y
It's simple.
x += 1 is the same as x = x + 1 while
x =+ 1 will make x have the value of (positive) one
Some historical perspective: Java inherited the += and similar operators from C. In very early versions of C (mid 1970s), the compound assignment operators had the "=" on the left, so
x =- 3;
was equivalent to
x = x - 3;
(except that x is only evaluated once).
This caused confusion, because
x=-1;
would decrement x rather than assigning the value -1 to it, so the syntax was changed (avoiding the horror of having to surround operators with blanks: x = -1;).
(I used -= and =- in the examples because early C didn't have the unary + operator.)
Fortunately, Java was invented long after C changed to the current syntax, so it never had this particular problem.
Because =+ is not a Java operator.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Is there a difference between x++ and ++x in java?
I am reading the official Java tutorial and I don't get the difference between postfix and prefix (++x vs x++). Could someone explain?
++x: increment x; the value of the overall expression is the value after the increment
x++: increment x; the value of the overall expression is the value before the increment
Consider these two sections:
int x = 0;
System.out.println(x++); // Prints 0
// x is now 1
int y = 0;
System.out.println(++y); // Prints 1
// y is now 1
I personally try to avoid using them as expressions within a larger statement - I prefer standalone code, like this:
int x = 0;
System.out.println(x); // Prints 0
x++;
// x is now 1
int y = 0;
y++;
System.out.println(y); // Prints 1
// y is now 1
Here I believe everyone would be able to work out what's printed and the final values of x and y without scratching their heads too much.
There are definitely times when it's useful to have pre/post-increment available within an expression, but think of readability first.
++x increments x and then returns the value
x++ returns the value of x and then increments the variable
For example:
int x = 0;
int A = ++x; // A = 1
int B = x++; // B = 1
int C = x; // C = 2
Well, you get enough answers, I'm going just to worry you... Both post- and pre-increment operators can confuse code, so sometimes it is better to use just x+1 then you and other people definitely know what is going on there. Some examples:
int x = 5;
x = ++x;
System.out.println( x ); // prints 6
x = x++;
System.out.println( x ); // prints 6!
x = ++x + x++;
System.out.println( x ); // prints 14!
two last incrementing can be a source of problems to debug then (was watching that few times in my life...). x = x++ - it is evaluated before incrementing... So be careful!
++x is pre-incrementing and x++ is post-incrementing. With post-incrementing the value is increased after evaluation and with pre-incrementing the value is increased before evaluation.
Well, standing alone it's the same. but, if there are other operands involved - ++x will advance x and then apply the other operands, and x++ will first use x and then advance it.
Basically, ++x adds 1 to x before x is evaluated, while x++ adds 1 afterwards. It makes sense if you use it as an argument.
Let's start with x
int x = 3;
If we call System.out.println on x using the infix operator:
System.out.println(++x);
x will first increase to 4 and the println will output, "4". It is pretty much the same if we did:
x+=1;
System.out.println(x);
Let's imagine x equals 3 again. If we call System.out.println on x using the postfix operator:
System.out.println(x++);
It will first output the current value of x, "3", and then increase x. So it's like:
System.out.println(x);
x+=1;
Hope that helps.