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?
System.out.println("Gotcha!");
instead of the comment? :)
.cross()
and the other is .dot()
and there is no confusion. Also the fact that "override the == operator and always return false" can't happen seems pro 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. ...
int x = 0;
if (x == x) {
System.out.println("Not ok");
} else {
System.out.println("Ok");
}
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.
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
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.
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;
}
}
}
a != a
because it was changed by another thread. I suspect this would win points in an interview.
a
is altered by the first thread in-between the first and second access for comparison
if
statement could be written in a single horrible line if necessary
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");
}
}
}
super.println
should be "Not ok", right?
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 :)
if (System.out.println("Gotcha") && false)
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");
}
}
}
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");
}
}
}
Success story sharing
else
altogether. This wouldn't technically violate the terms of the question.