答えられない質問が出てきました。
Javaに次のループ定義があるとします。
while (i == i) ;
ループが無限ループではなく、プログラムが1つのスレッドのみを使用している場合のタイプi
と値は何ですか?i
答えられない質問が出てきました。
Javaに次のループ定義があるとします。
while (i == i) ;
ループが無限ループではなく、プログラムが1つのスレッドのみを使用している場合のタイプi
と値は何ですか?i
回答:
double i = Double.NaN;
Double.equals()のAPI は、「Double.NaN == Double.NaNの値はfalseです」という答えを示しています。これは、Java言語仕様の「浮動小数点型、形式、および値」で詳しく説明されています。
NaN
数値比較演算子に、順不同で<
、<=
、>
、および>=
リターンfalse
の一方または両方のオペランドがある場合NaN
。等号演算子==
はfalse
、いずれかのオペランドがの場合に戻りNaN
、不等式演算子!=
はtrue
、いずれかのオペランドがの場合に戻りますNaN
。具体的には、x!=x
あるtrue
場合に限りx
、ISNaN
、及び(x<y) == !(x>=y)
あろうfalse
場合x
、またはy
ありますNaN
。
x == x
常に真実であるべきです。なぜ何かがそれ自体と等しくないはずですか?
null=null
nullです。NULL IS NULL
1です
の値i
は無効になります。「番号ではない」。
グーグルで調べたところ、JavaでNaN(非数)を使用できることがわかりました。したがって、浮動小数点数はデータ型であり、値はNaNです。こちらをご覧ください
他の人がそれがNaNであると言ったので、の公式(JDK 6)実装に興味を持ちましたDouble.isNaN
。
/**
* 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);
}
ナンは例外と同等であると考えてください。ただし、計算ではマジック値を使用します。計算が失敗したため-負の平方根、ゼロ除算など-他のものと比較しても意味がありません。結局、ゼロによる除算がnanである場合、それは-2の平方根または-3の平方根に相当しますか?
ナンは、余分な例外を導入することなく、無効な回答を返すステップを含む計算を完了することを許可します。答えが値であることを確認するには、同等のFloat.isNan()を介して単純に非ナンド(つまり、それをバッグしない場合はその単語)をテストします。
追加します
float i = Float.NaN;
と同様
double i = Double.NaN;
これらの種類の質問での一般的なトリックは、私がintであると仮定した場合です。その他の一般的な仮定として、sは文字列、x、yは倍精度、chは文字、bはバイトなどがあります。このような質問が表示された場合は、「i」が期待値タイプではないことに疑いの余地があります。
同様の質問です。これは決してループしない、「x」とは
while(x == x && x != x + 0) { }
私がかなり気に入っているもう1つの質問は、このループは無限ループです。xの可能な値は何ですか。(:私はそれらの12を数えます:)
while(x != 0 && x == -x) { }
私はこれがJavaの質問であることを知っていますが、他の言語の質問を検討することは興味深いものです。
Cでは、「i」が揮発性として宣言されている場合、「int」などの単純な型は「宇宙が冷える前に終了する」動作を示す可能性があります(そのため、コンパイラは反復ごとに「i」の2回の読み取りを強制されます)そして、「i」が実際にメモリにあり、他の何かがそれに影響を与える可能性がある場合。その後、1回の反復の2つの読み取り間で「i」が変更されると、ループが終了します。(追加:可能な場所-'i'が実際にはI / Oポートのアドレスに配置されているマイクロコンピューター内で、おそらく位置センサーに接続されています。'i 'がポインター変数である場合、よりもっともらしくなります(揮発性メモリへのポインタ)およびステートメントは ' while (*i == *i);
'でした。)
他の回答からもわかるように、C ++では、iがユーザー定義クラスの場合、ユーザーは '=='演算子を指定できるため、何でも可能です。
NaNのように、SQLベースの言語では、iの値がNULLの場合、ループは無限ではありません。ただし、NULL以外の値を指定すると、ループが無限になります。これはむしろJavaに似ており、(NaNとは対照的に)任意の数でループが無限になります。
私はこの構成が実際に使用されているとは思いませんが、興味深いトリビアの質問です。
私はこの解決策を見ていないことに驚きました:
while (sin(x) == sin(x)) //probably won't eval to true
コメントに応じて、これを実行してみてください:
double x = 10.5f;
assert (x == asin(sin(x)));
xは常に理論的にはアークサイン(sin(x))と等しくなければなりませんが、実際には等しくありません。
x
これはまったく同じ不正確さでまったく同じ結果をもたらすはずです。渡された値asin()
が正確ではないため、Arcsinは浮動小数点数を含むsinの結果を元に戻すことができません。したがって、の結果はasin()
不正確になり、誤りになりx == asin(sin(x))
ます。また、arcsinは必ずしもsin操作を「取り消す」とは限りません。sin関数は、xの複数の値に対して同じ結果をasin()
返す可能性があるため、-π/ 2とπ/ 2の間の数値のみを返します。
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);
}
更新 これは、無限ループではないもう1つの例です(新しいスレッドは作成されません)。
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);
}
}
while (i == i);
実行されません。