How can a Java variable be different from itself?
JavaIf StatementJava Problem Overview
I am wondering if this question can be solved in Java (I'm new to the language). This is the code:
class Condition {
// you can change in the main
public static void main(String[] args) {
int x = 0;
if (x == x) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
}
}
}
I received the following question in my lab: How can you skip the first case (i.e. make the x == x
condition false) without modifying the condition itself?
Java Solutions
Solution 1 - Java
One simple way is to use Float.NaN
:
float x = Float.NaN; // <--
if (x == x) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
}
Not ok
You can do the same with Double.NaN
.
From JLS §15.21.1. Numerical Equality Operators ==
and !=
:
>Floating-point equality testing is performed in accordance with the rules of the IEEE 754 standard:
>
>- If either operand is NaN, then the result of ==
is false
but the result of !=
is true
.
>
> Indeed, the test x!=x
is true
if and only if the value of x
is NaN.
>
>...
Solution 2 - Java
int x = 0;
if (x == x) {
System.out.println("Not ok");
} else {
System.out.println("Ok");
}
Solution 3 - Java
By the Java Language Specifications NaN
is not equal to NaN
.
Therefore any line that caused x
to be equal to NaN
would cause this, such as
double x=Math.sqrt(-1);
From the Java Language Specifications:
> Floating-point operators produce no exceptions (§11). An operation > that overflows produces a signed infinity, an operation that > underflows produces a denormalized value or a signed zero, and an > operation that has no mathematically definite result produces NaN. All > numeric operations with NaN as an operand produce NaN as a result. As > has already been described, NaN is unordered, so a numeric comparison > operation involving one or two NaNs returns false and any != > comparison involving NaN returns true, including x!=x when x is NaN.
Solution 4 - Java
Not sure if this is an option but changing x
from local variable to a field would allow other thread to change its value between the reading left and right side in if
statement.
Here is short demo:
class Test {
static int x = 0;
public static void main(String[] args) throws Exception {
Thread t = new Thread(new Change());
t.setDaemon(true);
t.start();
while (true) {
if (x == x) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
break;
}
}
}
}
class Change implements Runnable {
public void run() {
while (true)
Test.x++;
}
}
Output:
⋮
Ok
Ok
Ok
Ok
Ok
Ok
Ok
Ok
Not ok
Solution 5 - Java
The replaced line could read.
double x = Double.NaN;
This would cause the gotcha to be printed.
Java Language Specification (JLS) says:
> Floating-point operators produce no exceptions (§11). An operation that overflows produces a signed infinity, an operation that underflows produces a denormalized value or a signed zero, and an operation that has no mathematically definite result produces NaN. All numeric operations with NaN as an operand produce NaN as a result. As has already been described, NaN is unordered, so a numeric comparison operation involving one or two NaNs returns false and any != comparison involving NaN returns true, including x!=x when x is NaN.
Solution 6 - Java
I managed to get a Gotcha!
from this:
volatile Object a = new Object();
class Flipper implements Runnable {
Object b = new Object();
public void run() {
while (true) {
Object olda = a;
a = b;
a = olda;
}
}
}
public void test() {
new Thread(new Flipper()).start();
boolean gotcha = false;
while (!gotcha) {
// I've added everything above this - I would therefore say still legal.
if (a == a) {
System.out.println("Not yet...");
} else {
System.out.println("Gotcha!");
// Uncomment this line when testing or you'll never terminate.
//gotcha = true;
}
}
}
Solution 7 - Java
There are so many solutions:
import java.io.PrintStream;
class A extends PrintStream {
public A(PrintStream x) {
super(x);
}
public void println(String x) {
super.println("Not ok");
}
public static void main(String[] args) {
System.setOut(new A(System.out));
int x = 0;
if (x == x) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
}
}
}
Solution 8 - Java
One easy solution is:
System.out.println("Gotcha!");if(false)
if( a == a ){
System.out.println("Not yet...");
} else {
System.out.println("Gotcha!");
}
But I don't know all the rules to this riddle...
:) I know that this is a cheat, but without knowing all rules, is this the easiest solution to the question :)
Solution 9 - Java
Create your own class System
in tha same package with Condition
.
In this case your System
class will hide java.lang.System
class
class Condition
{
static class System
{
static class out
{
static void println(String ignored)
{
java.lang.System.out.println("Not ok");
}
}
}
public static void main (String[] args) throws java.lang.Exception
{
int x = 0;
if (x == x)
{
System.out.println("Not ok");
}
else
{
System.out.println("Ok");
}
}
}
Solution 10 - Java
Using the same skip/change output approach from another answers:
class Condition {
public static void main(String[] args) {
try {
int x = 1 / 0;
if (x == x) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
}
} catch (Exception e) {
System.out.println("Not ok");
}
}
}