Conditional Ternary Operations - java

First off, I came across this question recently and haven't being able to find a good explanation for it:
int x = (30 > 15)?(14 > 4) ? 1 : 0 : 2;
I have used ternary expression before so I am familiar with them, to be honest I don't even know what to call this expression... I think that it breaks down like this
if (con1) or (con2) return 1 // if one is correct
if (!con1) and (!con2) return 0 // if none are correct
if (con1) not (con2) return 2 // if one but not the other
Like I said I don't really know so I could be a million miles away.

Because of operator precedence in Java, this code:
int x = (30 > 15)?(14 > 4) ? 1 : 0 : 2;
will be parsed as if it were parenthesized as follows:
int x = (30 > 15) ? ((14 > 4) ? 1 : 0) : 2;
(The only operators with lower precedence than ternary ?: are the various assignment operators: =, +=, etc.) Your code can be expressed verbally as:
if (con1) and (con2) assign 1 to x
if (con1) and (not con2) assign 0 to x
otherwise assign 2 to x
EDIT: Nested ternary operators are often formatted in a special way to make the whole thing easier to read, particularly when they are more than two deep:
int x = condition_1 ? value_1 :
condition_2 ? value_2 :
.
.
.
condition_n ? value_n :
defaultValue; // for when all conditions are false
This doesn't work quite as cleanly if you want to use a ternary expression for one of the '?' parts. It's common to reverse the sense of a condition to keep the nesting in the ':' parts, but sometimes you need nesting in both branches. Thus, your example declaration could be rewritten as:
int x = (30 <= 15) ? 2 :
(14 > 4) ? 1 :
0 ;

It's int x = (30 > 15)?((14 > 4) ? 1 : 0): 2; :
if (30 > 15) {
if (14 > 4)
x = 1;
else
x = 0;
} else {
x = 2;
}

Related

What does a "+=" operator inside a ternary operator means?

I came across a code snippet inside the androidx.lifecycle package and I was wondering what does this means.
LiveData.this.mActiveCount += mActive ? 1 : -1;
Where mActiveCount is an int, and mActive is a boolean.
But, as I was writting this question, I think I came with the answer, so if I'm not mistaken the "+=" operator, is used as we normally use the "=" operator.
This means that the order in which the code executes is the following:
the mActive ? 1 : -1; portion executes first.
Once this is resolved, the LiveData.this.mActiveCount += mActive executes. So my real question is:
Is this the correct equivalence of this code?:
int intToAdd = mActive ? 1 : -1;
activeCount += intToAdd;
The operator += is not concerned with ternary operator.
You are checking for a condition using ternary operator and incrementing or decrementing it variable by 1.
a = a + b is equivalent to a += b, assuming we have declared a and b previously.
So, your code LiveData.this.mActiveCount += mActive ? 1 : -1; is equivalent to :-
if(mActive){
LiveData.this.mActiveCount += 1;
}
else{
LiveData.this.mActiveCount -= 1;
}
Your Logic below is also correct:-
int intToAdd = mActive ? 1 : -1;
activeCount += intToAdd;
This line of code adds either 1 or -1 to mAtiveCount, and looks at the boolean mActive to determine whether it adds +1 or -1.
It is exactly equivalent to this chunk of code, where I removed the usage of the tertiary operator and the += operator (and made their function explicit):
int amountToAdd;
if (mActive) {
amountToAdd = 1;
} else {
amountToAdd = -1;
}
LiveData.this.mActiveCount = LiveData.this.mActiveCount + amountToAdd;
I think the line is a bit unclear, but could be made more clear with the judicious use of parenthesis:
LiveData.this.mActiveCount += (mActive ? 1 : -1);
This can be answered by looking up Java operator precedence.
Assignment operators have the absolute lowest precedence, everything else happens first. The conditional expression mActive ? 1 : -1 is evaluated first. then the += is evaluated using the result of the condition expression.
Yes, you are right. There is something called as shorthand in java .
For example :
sum = sum + 1 can be written as sum += 1.
This statement :
LiveData.this.mActiveCount += mActive ? 1 : -1;
This statement really mean to say :
Either do this LiveData.this.mActiveCount += 1 or LiveData.this.mActiveCount += -1 based on mActive's value (true or false)

Java Arithmetic expression

The following expression evaluates to 14.
int a=4;
int b=6;
int c=1;
int ans= ++c + b % a - (c - b * c);
System.out.print(ans);
This is how i calculate this
1. (c - b * c) // since bracket has highest preference
ans : -5
2. ++c //since unary operator has next highest preference
ans : 2
3. b%a // % has higher preference than + and -
ans : 2
Therefore, 2 + 2 - (-5) = 9
As you can see I'm getting 9 as the value. Not sure what's wrong in my way of calculation (pretty sure I'm gonna end up looking stupid)
Edit : I refered to the below link for precedence and association.
https://introcs.cs.princeton.edu/java/11precedence/
Can someone explain the difference between level 16 and level 13 parentheses? I thought level 13 parentheses is used only for typecasting. That is why i considered level 16 parenthesis for evaluating the expression.
Evaluation order is not the same as precedence. Java always evaluates left-to-right (with a minor caveat around array accesses).
Effectively, you are evaluating the following expression, because the very first thing that happens is the pre-increment of c:
2 + 6 % 4 - (2 - 6 * 2)
Precedence then describes how the values are combined.
As you are using pre-increment operator on c. So, after applying increment on c the value of c will be 2. Now :
(c - b * c) will be evaluated to (2 - 6 * 2)= -10
So, the final expression will be 2 + 2 - (-10) = 14

What does the colon ":" and the question mark "?" operators do? [duplicate]

This question already has answers here:
What is a Question Mark "?" and Colon ":" Operator Used for? [duplicate]
(7 answers)
Closed 8 years ago.
What does the following line do? Could someone help me write this line in "normal" code?
int change = (Math.random() - 0.5 < 0 ? -5 : 5);
This is a ternary operator the way it works is :
condition ? (things to do if true) : (things to do if false);
In your code what it does is :
if value of Math.random() - 0.5 < 0
then assign change a values of -5
else
assign change a value of 5.
This line takes a random number (between 0 and 1) and subtracts 0.5. If that value is less than 0 then change is set to -5, otherwise 5.
int change;
if((Math.random() - 0.5) < 0)
{
change=-5;
}
else
{
change=5;
}

What is the meaning of "X ? a : b" notation? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the Java ?: operator called and what does it do?
In some code a ? is used to perform a mathematical equation.
What is it and how do you use it? Is it possible to provide an example and the reason for the final answer of an equation?
int count = getChildCount();
int top = count > 0 ? getChildAt(0).getTop() : 0;
Basically is the ternary operator:
String mood = (isHappy == true)?"I'm Happy!":"I'm Sad!";
if isHappy, then "I'm Happy!". "I'm Sad!" otherwise.
I presume you mean something like x = () ? y : z; notation? If that's the case, then the expression within the parentheses is evaluated as a boolean, if true x = y otherwise x = z
int count = getChildCount();
int top = count > 0 ? getChildAt(0).getTop() : 0;
Means that the top variable will contain the value of getChildAt(0).getTop() if the count variable is greater than 0, else it will equal to 0
My guess is you are referring to the ternary operator, which is used like this:
<some condition> ? <some value> : <some other value>;
For example:
int max = a > b ? a : b;
It's a shorthand for an if and is equivalent to:
int max;
if (a > b) {
max = a;
} else {
max = b;
}
but allows a one-line result in code.
When used well, it can make code much more clear due to its terseness. However caution is advised if the line becomes too long or complicated: The code only remains readable when the terms are brief.
The ? in an evaluative expression is called the ternary operator. It is essentially short-hand for an if() ... else block.
http://en.wikipedia.org/wiki/%3F:
I assume you're referring to the ternary operator. It's shorthand for certain kinds of if statements. Where you're making an assignment, like:
int dozen = (bakersDozen) ? 13 : 12;
Assuming bakersDozen is true, then dozen will be 13. If it's false, it will be 12.
int result = (a > b) ? 1 : 0;
is the same than
int result;
if (a > b)
result = 1;
else
result = 0;
? Is usually a ternary (or tertiary) operator. So let's explain what it is doing.
myValue = (a = b) ? 1 : 0;
The first part is your condition. "Does a equal b?"
The second part is the true response.
The third part is the false response.
So if a is equal to b, myValue will be 1. If a is not equal to b, myValue will be 0.
See http://en.wikipedia.org/wiki/Ternary_operation

signed to positive near-perfect hash

I have an integer type, say long, whose values are between Long.MIN_VALUE = 0x80...0 (-2^63) and Long.MAX_VALUE = 0x7f...f (2^63 - 1). I want to hash it with ~50% collision to a positive integer of the same type (i.e. between 1 and Long.MAX_VALUE) in a clean and efficient manner.
My first attempts were something like:
Math.abs(x) + 1
(x & Long.MAX_VALUE) + 1
but those and similar approaches always have problems with certain values, i.e. when x is 0 / Long.MIN_VALUE / Long.MAX_VALUE. Of course, the naive solution is to use 2 if statements, but I'm looking for something cleaner / shorter / faster. Any ideas?
Note: Assume that I'm working in Java where there is no implicit conversion to boolean and shift semantics is defined.
The simplest approach is to zero the sign bit and then map zero to some other value:
Long y = x & Long.MAX_VALUE;
return (y == 0)? 42: y;
This is simple, uses only one if/ternary operator, and gives ~50% collision rate on average. There is one disadvantage: it maps 4 different values (0, 42, MIN_VALUE, MIN_VALUE+42) to one value (42). So for this value we have 75% collisions, while for other values - exactly 50%.
It may be preferable to distribute collisions more evenly:
return (x == 0)? 42: (x == Long.MIN_VALUE) ? 142: x & Long.MAX_VALUE;
This code gives 67% collisions for 2 values and 50% for other values. You cannot distribute collisions more evenly, but it is possible to choose these 2 most colliding values. Disadvantage is that this code uses two ifs/ternary operators.
It is possible to avoid 75% collisions on single value while using only one if/ternary operator:
Long y = x & Long.MAX_VALUE;
return (y == 0)? 42 - (x >> 7): y;
This code gives 67% collisions for 2 values and 50% collisions for other values. There is less freedom choosing these most colliding values: 0 maps to 42 (and you can choose almost any value instead); MIN_VALUE maps to 42 - (MIN_VALUE >> 7) (and you can shift MIN_VALUE by any value from 1 to 63, only make sure that A - (MIN_VALUE >> B) does not overflow).
It is possible to get the same result (67% collisions for 2 values and 50% collisions for other values) without conditional operators (but with more complicated code):
Long y = x - 1 - ((x >> 63) << 1);
Long z = y + 1 + (y >> 63);
return z & Long.MAX_VALUE;
This gives 67% collisions for values '1' and 'MAX_VALUE'. If it is more convenient to get most collisions for some other values, just apply this algorithm to x + A, where 'A' is any number.
An improved variant of this solution:
Long y = x + 1 + ((x >> 63) << 1);
Long z = y - (y >> 63);
return z & Long.MAX_VALUE;
Assuming you want to collapse all values into the positive space, why not just zero the sign bit?
You can do this with a single bitwise op by taking advantage of the fact that MAX_VALUE is just a zero sign bit followed by ones e.g.
int positive = value & Integer.MAX_VALUE;
Or for longs:
long positive = value & Long.MAX_VALUE;
If you want a "better" hash with pseudo-random qualities, you probably want to pss the value through another hash function first. My favourite fast hashes are the XORshift family by George Marsaglia. These have the nice property that they map the entire int / long number space perfectly onto itself, so you will still get exactly 50% collisions after zeroing the sign bit.
Here's a quick XORshift implementation in Java:
public static final long xorShift64(long a) {
a ^= (a << 21);
a ^= (a >>> 35);
a ^= (a << 4);
return a;
}
public static final int xorShift32(int a) {
a ^= (a << 13);
a ^= (a >>> 17);
a ^= (a << 5);
return a;
}
I would opt for the most simple, yet not totally time wasting version:
public static long postiveHash(final long hash) {
final long result = hash & Long.MAX_VALUE;
return (result != 0) ? result : (hash == 0 ? 1 : 2);
}
This implementation pays one conditional operation for all but two possible inputs: 0 and MIN_VALUE. Those two are assigned different value mappings with the second condition. I doubt you get a better combination of (code) simplicity and (computational) complexity.
Of course if you can live with a worse distribution, it gets a lot simpler. By restricting the space to 1/4 instead of to 1/2 -1 you can get:
public static long badDistribution(final long hash) {
return (hash & -4) + 1;
}
You can do it without any conditionals and in a single expression by using the unsigned shift operator:
public static int makePositive(int x) {
return (x >>> 1) + (~x >>> 31);
}
If the value is positive, it probably can be used directly, else, invert all bits:
x >= 0 ? hash = x : hash = x ^ Long.MIN_VALUE
However, you should scramble this value a bit more if the values of x are correlated (meaning: similar objects produce similar values for x), maybe with
hash = a * (hash + b) % (Long.MAX_VALUE) + 1
for some positive constants a and b, where a should be quite large and b prevents that 0 is always mapped to 1. This also maps the whole thing to [1,Long.MAX_VALUE] instead of [0,Long.MAX_VALUE]. By altering the values for a and b you could also implement more complex hash functionalities like cooko hashing, that needs two different hash functions.
Such a solution should definitely be preferred instead of one that delivers "strange collision distribution" for the same values each time it is used.
From the information theoretic view, you have 2^64 values to map into 2^63-1 values.
As such, mapping is trivial with the modulus operator, since it always has a non-negative result:
y = 1 + x % 0x7fffffffffffffff; // the constant is 2^63-1
This could be pretty expensive, so what else is possible?
The simple math 2^64 = 2 * (2^63 - 1) + 2 says we will have two source values mapping to one target value except in two special cases, where three will go to one. Think of these as two special 64-bit values, call them x1 and x2, that each share a target with two other source values. In the mod expression above, this occurs by "wrapping". The target values y=2^31-2 and y=2^31-3 have three mappings. All others have two. Since we have to use something more complex than mod anyway, let's seek a way to map the special values wherever we like at low cost
For illustration let's work with mapping a 4-bit signed int x in [-8..7] to y in [1..7], rather than the 64-bit space.
An easy course is to have x values in [1..7] map to themselves, then the problem reduces to mapping x in [-8..0] to y in [1..7]. Note there are 9 source values here and only 7 targets as discussed above.
There are obviously many strategies. At this point you can probably see a gazzilion. I'll describe only one that's particularly simple.
Let y = 1 - x for all values except special cases x1 == -8 and x2 == -7. The whole hash function thus becomes
y = x <= -7 ? S(x) : x <= 0 ? 1 - x : x;
Here S(x) is a simple function that says where x1 and x2 are mapped. Choose S based on what you know about the data. For example if you think high target values are unlikely, map them to 6 and 7 with S(x) = -1 - x.
The final mapping is:
-8: 7 -7: 6 -6: 7 -5: 6 -4: 5 -3: 4 -2: 3 -1: 2
0: 1 1: 1 2: 2 3: 3 4: 4 5: 5 6: 6 7: 7
Taking this logic up to the 64-bit space, you'd have
y = (x <= Long.MIN_VALUE + 1) ? -1 - x : x <= 0 ? 1 - x : x;
Many other kinds of tuning are possible within this framework.
Just to make sure, you have a long and want to hash it to an int?
You could do...
(int) x // This results in a meaningless number, but it works
(int) (x & 0xffffffffl) // This will give you just the low order bits
(int) (x >> 32) // This will give you just the high order bits
((Long) x).hashcode() // This is the high and low order bits XORed together
If you want to keep a long you could do...
x & 0x7fffffffffffffffl // This will just ignore the sign, Long.MIN_VALUE -> 0
x & Long.MAX_VALUE // Should be the same I think
If getting a 0 is no good...
x & 0x7ffffffffffffffel + 1 // This has a 75% collision rate.
Just thinking out loud...
((x & Long.MAX_VALUE) << 1) + 1 // I think this is also 75%
I think you're going to need to either be ok with 75% or get a little ugly:
(x > 0) ? x : (x < 0) ? x & Long.MAX_VALUE : 7
This seems the simplest of all:
(x % Long.MAX_VALUE) + 1
I would be interested in speed comparisons of all the methods given.
Just AND your input value with Long.MAX_VALUE and OR it with 1. Nothing else needed.
Ex:
long hash = (input & Long.MAX_VALUE) | 1;

Categories

Resources