const
(только для C ++) Для людей, прибывающих с C, может показаться неожиданным, что в C ++ глобальные переменные const
имеют внутренние (или статические) связь. В C это не так, поскольку все глобальные переменные неявно extern
(т.е. когда отсутствует ключевое слово static
).
Пример:
// file1.cpp
const int test = 5; // in C++ same as "static const int test = 5"
int test2 = 5;
// file2.cpp
extern const int test;
extern int test2;
void foo()
{
int x = test; // linker error in C++ , no error in C
int y = test2; // no problem
}
correct would использовать файл заголовка и включить его в file2.cpp и file1.cpp
extern const int test;
extern int test2;
. В качестве альтернативы можно было бы объявить переменную const
в файле file1.cpp с явным extern
Один простой способ - использовать Float.NaN
:
float x = Float.NaN; // <--
if (x == x) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
}
Not ok
Вы можете сделать то же самое с Double.NaN
.
Из JLS §15.21.1. Операторы числового равенства ==
и !=
:
Тестирование равенства по плавающей запятой выполняется в соответствии с правилами стандарта IEEE 754:
- Если любой из операндов равен NaN, то результатом
==
являетсяfalse
, но результатом!=
являетсяtrue
. Действительно, тестx!=x
равенtrue
тогда и только тогда, когда значениеx
равно NaN....
blockquote>
Одно из простых решений:
System.out.println("Gotcha!");if(false)
if( a == a ){
System.out.println("Not yet...");
} else {
System.out.println("Gotcha!");
}
Но я не знаю всех правил этой загадки ...
:) Я знаю, что это чит, но не зная всех правил, это самое легкое решение вопроса:)
Используя один и тот же подход пропуска / изменения вывода из другого ответа:
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");
}
}
}
Создайте свой собственный класс System
в том же пакете с Condition
. В этом случае ваш класс System
скроет класс java.lang.System
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");
}
}
}
int x = 0;
if (x == x) {
System.out.println("Not ok");
} else {
System.out.println("Ok");
}
Существует так много решений:
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");
}
}
}
Мне удалось получить Gotcha!
из этого:
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;
}
}
}
В соответствии с спецификациями языка Java NaN
не равно NaN
.
Поэтому любая строка, которая привела к x
равным NaN
, это, например
double x=Math.sqrt(-1);
Из спецификации языка Java:
Операторы с плавающей точкой не вызывают исключений (§11). Операция, которая переполняет, создает подписанную бесконечность, операция, которая выполняется под потоком, создает денормализованное значение или подписанный нуль, а операция, не имеющая математически определенного результата, дает NaN. В результате числовые операции с NaN в качестве операнда дают NaN. Как уже было описано, NaN неупорядочен, поэтому операция числового сравнения с одним или двумя NaN возвращает false, а любое! = Сравнение с NaN возвращает true, включая x! = X, когда x является NaN.
blockquote>