私はこの記事読んだことが、負と正のゼロを。
私の理解、次のコードに与えるべきであるtrue
とtrue
出力など。
しかし、それは与えているfalse
とtrue
出力など。
私は、正のゼロと負のゼロを比較しています。
public class Test {
public static void main(String[] args) {
float f = 0;
float f2 = -f;
Float F = new Float(f);
Float F1 = new Float(f2);
System.out.println(F1.equals(F));
int i = 0;
int i2 = -i;
Integer I = new Integer(i);
Integer I1 = new Integer(i2);
System.out.println(I1.equals(I));
}
}
なぜ0のための異なる振る舞いを持っていますInteger
とFloat
?
INTSとフロートは、Javaではかなり異なる獣です。int値は次のように符号化される2の補数単一0の値を有します。フロートは、使用IEEE 754(32ビットバリアントフロートのため、および64ビットの倍精度のために)。IEEE 754は、やや複雑ですが、この回答の目的のために、あなたはそれが符号ビットである最初のうち3つのセクションが、持っていることを知っておく必要があります。浮動小数点のための手段が、正と負のvariant¹があります。つまり、0を含むので、実際には二つの「ゼロ」値を有する浮上+0と-0。
余談として、int型が使用する2の補数は、コンピュータサイエンスのエンコード整数への唯一の方法ではありません。他にも方法は次のように、あるの補数が、彼らは癖を持っている-個別の値として+0と-0の両方を持っているようなもの。;-)
あなたはフロートプリミティブ(ダブルス)を比較すると、Javaは+0と-0同じ扱いです。あなたがそれらをボックスする際に説明するように、Javaは、それらを別々に扱いますFloat#equals
。これは、方法は、それらと一致して等しくすることができhashCode
実装(ならびにcompareTo
同様-あるINTにそれらを(その署名された値を含む)フロートのビットを使用し、突きつけています)。
彼らはイコール/のhashCode /のcompareToのためのいくつかの他のオプションを選んだ可能性が、彼らはしませんでした。私は、設計上の考慮事項があったかわからないんだけど。しかし、少なくとも一つの点で、Float#equals
常にフロートプリミティブのから分岐するつもりだった==
:プリミティブでは、NaN != NaN
しかし、すべてのオブジェクトに対して、o.equals(o)
また真でなければなりません。ことを意味し、あなたが持っていた場合Float f = Float.NaN
、その後f.equals(f)
にもかかわらずf.floatValue() != f.floatValue()
。
¹(でも発注用)はNaN(非数)の値は、符号ビットを持っているが、それは順序以外の任意の意味を持っていない、とJavaはそれを無視します。