This question already has answers here:
What is the difference between += and =+?
(9 answers)
What is the purpose of the =+ operator in Java? [duplicate]
(2 answers)
Closed 9 years ago.
I've the following code:
public class Operators {
public static void main(String[] args) {
int i =+ 2;
System.out.println(i);
}
}
Upon executing I'm getting the following output: 2
So what does =+ operator actually does here?
EDIT:
As some answered, it is assigning +2 to i, consider the following code:
public class Operators {
public static void main(String[] args) {
int i =- -2;
System.out.println(i);
}
}
So in above case, output should be -2. But I'm getting 2
So I suppose, it is -(-2), which gives 2. Right?
int i =+ 2;
It is positive 2(+2) assignment to variable i. It is more miningful or understandable if your write like -- int i = +2;
One more example -
int i = 2;
i=+3;
System.out.println(i);
It prints 3.
+ Unary plus operator; indicates
positive value (numbers are
positive without this, however)
More example - http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/java/nutsandbolts/examples/UnaryDemo.java
Upon saying:
int i =+ 2;
+ acts as a unary operator.
To elaborate, it sets i to a positive value 2.
EDIT: Your update says:
int i =- -2;
produces 2. Why?
In this case, it implies that i=-(-(2)). Note that using a unary minus operator might produce unexpected results when the value is, say, Integer.MIN_VALUE.
I believe what you mean by =+ is really +=.
Your code is assigning the value of +2 (positive 2) to the integer.
For example:
int x =+ 4;
x =+ 8;
Console.WriteLine(x.ToString());
Console.ReadLine();
Will print "8", not 12. This is because you are assigning x to +4 and then +8.
If you are asking about what += does, it is a shorthand to takes the initial variable and add to it.
x += 8
is the same as
x = x + 8
By changing the previous example form =+ to += give us:
int x = 4;
x += 8;
Console.WriteLine(x.ToString());
Console.ReadLine();
Will print "12".
You are setting i equal to +2, which is what you got. What kind of output are you expecting?
Refer to the following image for unary operators.
Here is an exmaple to understand it.
public class UnaryDemo {
public static void main(String[] args) {
int x = 10;
int y = 20;
int result = +x;
System.out.println("+x = " + result);
result = -y;
System.out.println("-y = " + result);
}
}
and the output is
+x = 10
-y = -20
So think the operator as variable = +value rather than variable =+ values. yeah That space makes it more readable.
As all others are answered, I want to give the JLS reference.
Answer to your Edit
int i =- -2;
As specified in jls
Unary numeric promotion (§5.6.1) is performed on the operand.
The type of the unary minus expression is the promoted type of the operand.
At run time, the value of the unary minus expression is the arithmetic negation of the promoted value of the operand.
So,
System.out.println(i); //prints 2
For integer values, negation is the same as subtraction from zero.
Note
For floating-point values, negation is not the same as subtraction from zero, because if x is +0.0, then 0.0-x is +0.0, but -x is -0.0.
Unary minus merely inverts the sign of a floating-point number. Special cases of interest:
If the operand is NaN, the result is NaN. (Recall that NaN has no sign (§4.2.3).)
If the operand is an infinity, the result is the infinity of opposite sign.
If the operand is a zero, the result is the zero of opposite sign.
Useful links
unary operators
Unary Numeric Promotion
Related
This question already has answers here:
Java: parse int value from a char
(9 answers)
Closed 5 years ago.
I am trying to fetch second digit from a long variable.
long mi = 110000000;
int firstDigit = 0;
String numStr = Long.toString(mi);
for (int i = 0; i < numStr.length(); i++) {
System.out.println("" + i + " " + numStr.charAt(i));
firstDigit = numStr.charAt(1);
}
When I am printing firstDigit = numStr.charAt(1) on console. I am getting 1 which is expected but when the loop finishes firstDigit has 49.
Little confused why.
Because 49 is the ASCII value of char '1'.
So you should not assign a char to int directly.
And you don't need a loop here which keeps ovveriding the current value with charAt(1) anyway.
int number = numStr.charAt(1) - '0'; // substracting ASCII start value
The above statement internally works like 49 -48 and gives you 1.
If you feel like that is confusious, as others stated use Character.getNumericValue();
Or, although I don't like ""+ hack, below should work
int secondDigit = Integer.parseInt("" + String.valueOf(mi).charAt(1));
You got confused because 49 is ASCII value of integer 1. So you may parse character to integer then you can see integer value.
Integer.parseInt(String.valueOf(mi).charAt(1)):
You're probably looking for Character.getNumericValue(...) i.e.
firstDigit = Character.getNumericValue(numStr.charAt(1));
Otherwise, as the variable firstDigit is of type int that means you're assigning the ASCII representation of the character '1' which is 49 rather than the integer at the specified index.
Also, note that since you're interested in only a particular digit there is no need to put the statement firstDigit = numStr.charAt(1); inside the loop.
rather, just do the following outside the loop.
int number = Character.getNumericValue(numStr.charAt(1));
you only need define firstDigit as a char type variable, so will print as character.
since you define as int variable, it's value is the ASCII value of char '1': 49. this is why you get 49 instead of 1.
the answer Integer.parseInt(String.valueOf(mi).charAt(1)+""); is correct.
However, if we want to consider performace in our program, we need some improvements.
We have to time consuming methods, Integer.parseInt() and String.valueOf(). And always a custom methods is much faster than Integer.parseInt() and String.valueOf(). see simple benchmarks.
So, high performance solution can be like below:
int y=0;
while (mi>10)
{
y=(int) (mi%10);
mi=mi/10;
}
System.out.println("Answer is: " + y);
to test it:
long mi=4642345432634278834L;
int y=0;
long start = System.nanoTime();
//first solution
//y=Integer.parseInt(String.valueOf(mi).charAt(1)+"");
//seconf solution
while (mi>10)
{
y=(int) (mi%10);
mi=mi/10;
}
long finish = System.nanoTime();
long d = finish - start;
System.out.println("Answer is: " + y + " , Used time: " + d);
//about 821 to 1232 for while in 10 runs
//about 61225 to 76687 for parseInt in 10 runs
Doing string manipulation to work with numbers is almost always the wrong approach.
To get the second digit use the following;
int digitnum = 2;
int length = (int)Math.log10(mi));
int digit = (int)((mi/Math.pow(base,length-digitnum+1))%base);
If you want a different digit than the second change digitnum.
To avoid uncertainty with regards to floating point numbers you can use a integer math library like guavas IntMath
Let's take a look
System.out.println(numStr.charAt(1));
firstDigit = numStr.charAt(1);
System.out.println(firstDigit);
The result wouldn't be the same you will get
1
49
This happens because your firstDigit is int. Change it to char and you will get expected result
You can also do like below,
firstDigit = Integer.parseInt( numStr.charAt(1)+"");
So it will print second digit from long number.
Some things which have not been mentioned yet:
The second digit for integer datatypes is undefined if the long number is 0-9 (No, it is not zero. Integers do not have decimal places, this is only correct for floating-point numbers. Even then you must return undefined for NaN or an infinity value). In this case you should return a sentinel like e.g. -1 to indicate that there is no second digit.
Using log10 to get specific digits looks elegant, but they are 1. one of the numerically most expensive functions and 2. do often give incorrect results in edge cases. I will give some counterexamples later.
Performance could be improved further:
public static int getSecondDigit(long value) {
long tmp = value >= 0 ? value : -value;
if (tmp < 10) {
return -1;
}
long bigNumber = 1000000000000000000L;
boolean isBig = value >= bigNumber;
long decrement = isBig ? 100000000000000000L : 1;
long firstDigit = isBig ? bigNumber : 10;
int result = 0;
if (!isBig) {
long test = 100;
while (true) {
if (test > value) {
break;
}
decrement = firstDigit;
firstDigit = test;
test *= 10;
}
}
// Remove first
while (tmp >= firstDigit) {
tmp -= firstDigit;
}
// Count second
while (tmp >= decrement) {
tmp -= decrement;
result++;
}
return result;
}
Comparison:
1 000 000 random longs
String.valueOf()/Character.getNumericValue(): 106 ms
Log/Pow by Taemyr: 151 ms
Div10 by #Gholamali-Irani: 45 ms
Routine above: 30 ms
This is not the end, it can be even faster by lookup tables
decrementing 1/2/4/8, 10/20/40/80 and avoid the use of multiplication.
try this to get second char of your long
mi.toString().charAt(1);
How to get ASCII code
int ascii = 'A';
int ascii = 'a';
So if you assign a character to an integer, the integer will be holding the ASCII value of that character. Here I explicitly gave the values, in your code you are calling a method that returns a character, that's why you are getting ASCII instead of digit.
Here are the specifics.
Say I have an integer 3.
How can I determine if 3 occurs in the any of the decimal places of a double. Say 0.098734. I understand you can cast the double as a String and then search the string, but is there a way to do it with modulus or some other means?
A double has is not exact and the difference to the next double varies.
So consider that a double has at most a precision of ca 17 digits, then:
boolean hasDecimalDigit(double x, int digit) {
if (x < 0) {
x = -x;
}
for (int i = 0; i < 17; ++i) {
x *= 10;
if (((int)x) % 10) == digit) {
return true;
}
}
return false;
}
This may very well be not in concordance with the String representation,
which often is a bit beautified.
Also there are limitations, overflow. Taking first modulo 1 may diminish some effects, but even taken modulo already may introduce garbage precision for huge numbers.
For maintaining a precision use BigDecimal as in:
BigDecimal x = new BigDecimal("0.098734");
This gives an exact fixed-point math with precision.
Convert to a string (like you'd do when printing it out) and then do a charAt or indexOf comparison
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.
The following code sample prints 1.5.
float a = 3;
float b = 2;
a /= b;
System.out.println(a);
I don't understand what the /= operator does. What is it supposed to represent?
It's a combination division-plus-assignment operator.
a /= b;
means divide a by b and put the result in a.
There are similar operators for addition, subtraction, and multiplication: +=, -= and *=.
%= will do modulus.
>>= and <<= will do bit shifting.
It is an abbreviation for x = x / y (x /= y). What it does is it divides the variable to be asigned by the left hand side of it and stores it in the right hand side. You can always change:
x = x / y
to
x /= y
You can do this with most other operators like * / + and -. I am not sure about bitwise operators though.
a/=b; implies that divide a with b and put the result into a
A/=B means the same thing as A=(A/B)
Java (copying from C) has a whole set of operators X op = Y meaning X=X op Y, for op being any of: + - * / % & | ^
X/=Y it is same as X=X/Y.
Also you can try the same thing for these operators + - * %
As most people here have already said, x/=y is used as a shortened form of x=x\y and the same works for other operators like +=, -=, *=, %=. There's even further shortcuts for + and - where x++ and x-- represent x=x+1 and x=x-1 respectively.
One thing that hasn't been mentioned is that if this is used in some function call or conditional test the original value is used then replaced, letting you do the iterator for a while loop inside the call that uses that iterator, or write a true mod function using the remainder operator much more concisely:
public int mod(int a, int b){
return ((a%=b)>=0?a:a+b);
}
which is a much shorter way of writing:
public int mod(int a, int b){
a = a % b
if (a>=0){
return a;
}
return a+b;
}
You could say a = a / b OR (for short) say a /= b
A simple comparison of two double values in Java creates some problems. Let's consider the following simple code snippet in Java.
package doublecomparision;
final public class DoubleComparision
{
public static void main(String[] args)
{
double a = 1.000001;
double b = 0.000001;
System.out.println("\n"+((a-b)==1.0));
}
}
The above code appears to return true, the evaluation of the expression ((a-b)==1.0) but it doesn't. It returns false instead because the evaluation of this expression is 0.9999999999999999 which was actually expected to be 1.0 which is not equal to 1.0 hence, the condition evaluates to boolean false. What is the best and suggested way to overcome such a situation?
Basically you shouldn't do exact comparisons, you should do something like this:
double a = 1.000001;
double b = 0.000001;
double c = a-b;
if (Math.abs(c-1.0) <= 0.000001) {...}
Instead of using doubles for decimal arithemetic, please use java.math.BigDecimal. It would produce the expected results.
For reference take a look at this stackoverflow question
You can use Double.compare; It compares the two specified double values.
int mid = 10;
for (double j = 2 * mid; j >= 0; j = j - 0.1) {
if (j == mid) {
System.out.println("Never happens"); // is NOT printed
}
if (Double.compare(j, mid) == 0) {
System.out.println("No way!"); // is NOT printed
}
if (Math.abs(j - mid) < 1e-6) {
System.out.println("Ha!"); // printed
}
}
System.out.println("Gotcha!");
Consider this line of code:
Math.abs(firstDouble - secondDouble) < Double.MIN_NORMAL
It returns whether firstDouble is equal to secondDouble. I'm unsure as to whether or not this would work in your exact case (as Kevin pointed out, performing any math on floating points can lead to imprecise results) however I was having difficulties with comparing two double which were, indeed, equal, and yet using the 'compareTo' method didn't return 0.
I'm just leaving this there in case anyone needs to compare to check if they are indeed equal, and not just similar.
Just use Double.compare() method to compare double values.
Double.compare((d1,d2) == 0)
double d1 = 0.0;
double d2 = 0.0;
System.out.println(Double.compare((d1,d2) == 0)) // true
double a = 1.000001;
double b = 0.000001;
System.out.println( a.compareTo(b) );
Returns:
-1 : 'a' is numerically less than 'b'.
0 : 'a' is equal to 'b'.
1 : 'a' is greater than 'b'.