Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java “怎么可能?”;而(i==i)&引用;在单线程应用程序中是否为非无限循环?_Java - Fatal编程技术网

Java “怎么可能?”;而(i==i)&引用;在单线程应用程序中是否为非无限循环?

Java “怎么可能?”;而(i==i)&引用;在单线程应用程序中是否为非无限循环?,java,Java,我只是有一个我无法回答的问题 假设您在Java中有以下循环定义: while (i == i) ; 如果循环不是无限循环且程序仅使用一个线程,则i的类型和值是什么?则i的值无效。“不是数字” 通过谷歌搜索,我发现你可以在Java中使用NaN(不是一个数字)!因此,浮点数是数据类型,值为NaN。看 的API给出了答案:“Double.NaN==Double.NaN的值为false”。Java语言规范在“”下对此进行了详细说明: NaN是无序的,因此 比较运算符= 返回false如果其中一个或两个

我只是有一个我无法回答的问题

假设您在Java中有以下循环定义:

while (i == i) ;

如果循环不是无限循环且程序仅使用一个线程,则
i
的类型和值是什么?

i
的值无效。“不是数字”

通过谷歌搜索,我发现你可以在Java中使用NaN(不是一个数字)!因此,浮点数是数据类型,值为NaN。看

的API给出了答案:“Double.NaN==Double.NaN的值为false”。Java语言规范在“”下对此进行了详细说明:

NaN
是无序的,因此 比较运算符
=
返回
false
如果其中一个或两个 操作数是
NaN
。这个 相等运算符
==
返回
false
if 任一操作数为NaN,且 不等式运算符
=返回
true
if 任一操作数都是
NaN
In 特别是,
x=x
当且仅当 如果
x
NaN
,并且
(x=y)
将 如果
x
y
NaN
,则为
false


NaN不等于任何东西,包括它本身。

将NaN视为异常的等价物,但在计算中使用了一个神奇的值。因为计算失败——例如负数的平方根,被零除等等——将它们与其他任何东西进行比较是没有意义的。毕竟,如果除以零是一个nan,那么它等于-2的平方根还是-3的平方根


Nan允许一个计算,该计算包含一个步骤,该步骤返回一个无效答案以完成,而不会引入额外的异常。要验证答案是否为value,只需通过Float.isNan()o等效项测试非nandness(即如果不是,则将其打包)

我不确定,但我相信(I==I)在多线程进程中不是原子操作,因此,如果在执行循环的线程上,其他线程将I值推送到堆栈上,则该条件可能是错误的。

我知道这是一个Java问题,但考虑其他语言的问题很有趣

在C语言中,如果“i”被声明为volatile(因此编译器将被迫在每次迭代中读取两次“i”),并且“i”实际上在内存中,而其他东西可能会影响它,那么像“int”这样的简单类型可能会表现出“在宇宙变冷之前终止”的行为。然后,当“i”在单个迭代的两次读取之间发生更改时,循环将终止。(增加:一个可能的位置-在微型计算机中,“i”实际上位于i/O端口的地址,可能连接到位置传感器。如果“i”是指针变量(指向易失性存储器的指针),并且语句是“
while(*i==*i);
”,则更合理。)

如其他答案所证明的,在C++中,如果用户是用户定义的类,则可以提供用户''==''操作符,所以任何事情都是可能的。 与NaN类似,在基于SQL的语言中,如果i的值为NULL,循环就不会是无限的;但是,任何非空值都会使循环无限大。这很像Java,任何数字(与NaN相反)都会使循环无限

我不认为这个构造有任何实际用途,但这是一个有趣的琐事问题。

我想补充一点

float i = Float.NaN;
以及

double i = Double.NaN;

这类问题的一个常见技巧是假设i是int。其他常见的假设可能是s是字符串,x,y是双精度的,ch是字符,b是字节等等。 如果你看到这样的问题,你可以打赌“i”不是它所期望的类型

类似的问题是;这永远不会循环,什么是“x”

while(x == x && x != x + 0) { }
另一个我很喜欢的问题是;这个循环是一个无限循环,x的可能值是多少。(:正如@Clement在下面指出的那样,我数了四个:)


我很惊讶没有看到这个解决方案:

while (sin(x) == sin(x)) //probably won't eval to true
作为对注释的响应,请尝试运行以下命令:

double x = 10.5f;
assert (x == asin(sin(x)));

理论上,x应始终等于反正弦(sin(x)),但实际上并非如此

i==i
不是原子的。该程序证明:

static volatile boolean i = true;
public static void main(String[] args) throws InterruptedException
{
    new Thread() {
        @Override
        public void run() {
            while (true) {
                i = !i;
            }
        }
    }.start();

    while (i == i) ;
    System.out.println("Not atomic! i: " + i);
}
更新 这里还有一个非无限循环的例子(没有创建新线程)


非无限循环,一个线程:)


由于其他人说它是NaN,我对
Double.isNaN
的官方(JDK 6)实现感到好奇,看看:

/**
 * Returns <code>true</code> if the specified number is a
 * Not-a-Number (NaN) value, <code>false</code> otherwise.
 *
 * @param   v   the value to be tested.
 * @return  <code>true</code> if the value of the argument is NaN;
 *          <code>false</code> otherwise.
 */
static public boolean isNaN(double v) {
    return (v != v);
}

是的,就是这样。我的价值观是乔恩·斯基特。我通常讨厌那些无缘无故否决投票的人。。。我是第一个说“不是一个数字”的人,但我不认为java能处理这个问题,因为它不能处理任何其他很酷的事情!它在数学上是可靠的,为什么一个不真实的数字应该等于另一个?5/0 != sqrt(-4)@CrazyJugglerDrummer:也许吧,但同样地,
x==x
应该总是正确的。巴特:因为真的,未知并不总是等于未知。有时它很有用,这就是为什么数据库有NULL…@inovaovao:no,在数据库中,
NULL=NULL
是NULL
NULL为NULL
IS 1。哦,看在上帝的份上,人们是否有幸评论一下他们为什么否决投票?这被贴上了谜语的标签,有什么问题吗?我想有些人无法停止对任何事情的否决投票。呸,很抱歉造成这种情况:/我真的只是想要答案,但我自己无法解决。@nickolai,不幸的是,这就是所谓的“通过向下投票推动”的本质,要求发表评论的想法已经被讨论和拒绝。但看起来“社区”最终还是支持这个问题。这类问题的诀窍之一是人们假设某些变量名的类型,即i是int,d是double,s是string或short,ch是char,l是lon
while (sin(x) == sin(x)) //probably won't eval to true
double x = 10.5f;
assert (x == asin(sin(x)));
static volatile boolean i = true;
public static void main(String[] args) throws InterruptedException
{
    new Thread() {
        @Override
        public void run() {
            while (true) {
                i = !i;
            }
        }
    }.start();

    while (i == i) ;
    System.out.println("Not atomic! i: " + i);
}
public class NoNewThreads {
    public static void main(String[] args) {
        new NoNewThreads();
        System.gc();
        int i = 500;
        System.out.println("Still Running");
        while (i == i) ;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        Thread.sleep(1000);
        System.exit(0);
    }
}
import static B.*;
public class A {
    public static void main(String[] args) {
        System.out.println("Still Running");
        while (i == i) ;
    }
}


public class B {

    public static int i;
    static {
        System.exit(0);
    }
}
/**
 * Returns <code>true</code> if the specified number is a
 * Not-a-Number (NaN) value, <code>false</code> otherwise.
 *
 * @param   v   the value to be tested.
 * @return  <code>true</code> if the value of the argument is NaN;
 *          <code>false</code> otherwise.
 */
static public boolean isNaN(double v) {
    return (v != v);
}