3

2つの質問があります。

Float1)2つまたはDoubleデータを比較するときは、compareToの代わりに使用すると言われましたequals。理由はわかりません。使用すると何か問題が発生することを示す例はありますequalsか?

2)このコードを参照してください:

  float f2=(float)1.123450;
  Float f3=new Float(1.123450);

  System.out.println(f3==f2);   // result is true

==使用とは、2つのデータが同じメモリアドレスを指していることを意味すると思います。しかし、同じアドレスf3を持っていますか?新しい空間を作り f2ませんか?new Float(...)

4

3 に答える 3

12

両方の引数が参照型の場合、==メモリ位置をテストします。ただし、==(または!=)の引数の1つが数値で、もう1つが(ボックス化解除を使用して)数値に変換可能である場合、ボックス化解除後に数値を比較することによって比較が行われます。したがって、この場合の比較は、浮動小数点値(この場合は同一)に基づいて行われます。詳細については、Java言語仕様§15.21.1を参照してください。

ただし、それFloat.NaN == Float.NaNfalseです。

于 2012-10-25T14:53:09.230 に答える
8

丸めエラーや算術エラーを処理する必要がない限り、一般的に==は問題ありません。その場合、compareTo()はあまり役に立ちません。

エラー内で2つのダブルを比較したい場合は、次を使用できます。

if (Math.abs(a - b) < ERR) // within error.

または相対誤差

if (Math.abs(a - b) < ERR * (Math.abs(a) + Math.abs(b))/2) // within error.

または、係数が10000のように10の累乗であるかどうかを四捨五入すると、小数点以下4桁になります。

if (Math.round(a * factor) == Math.round(b * factor)) // within a multiple
于 2012-10-25T14:54:24.887 に答える
2

Javaには、2つの(プライマリ)タイプがあります。

  1. プリミティブ
  2. 参照

    doubleプリミティブ型は、タイプがfloat、、、、などである場合にのみ、プリミティブと見なさintlongます。

    参照型は、「オブジェクト」を使用してデータを格納する任意の型です。クラスで作成しているときは、実際には「変装した」参照型を作成しています。参照型の例としては、、、などがStringありDoubleますInteger

    したがって、タイプに関する限り、と比較すると、実際には2つの異なるタイプを比較float xしています。Float y

    Javaでは==、ほとんどの場合、の演算子は同じタイプのオブジェクトのみを比較します。ただし、プリミティブであり、参照型(上記で定義)x == yである場合など、言語によって他の型の比較が許可される場合があります。xy

    xとの比較yが行われると、ボクシングとアンボクシングと呼ばれる操作が実行されます。ただし、ボクシングを理解するには、メモリセマンティクスの観点からプリミティブ型と参照型の違いを理解する必要があります。(それであなたを怖がらせないでください!)

    プリミティブ型はスタックと呼ばれるメモリ位置に格納されます。スタックは高速であり、断片化されたアクセスに関してはあまり柔軟性がありません。とても簡単です。

    ただし、参照型は異なります。演算子を使用して参照型がインスタンス化さnewれる場合(実行時に暗黙的に呼び出されます。つまりFloat x = <something>;Float x = <something>;に変換されますFloat x = new Float(<something>);)。したがって、Floatまたは他の参照型がインスタンス化されると、オブジェクトが作成され、ヒープに格納されます。 、ただし、そのオブジェクト(ヒープ上にある)へのポインターはスタックに格納されます。

    これは、に格納されている値を取得するためにx、コンピュータはスタックに格納されているアドレスを使用し、ヒープ内のそのメモリアドレスに移動する必要があることを意味します。

    スタックは「動的メモリ割り当て」と呼ばれるものがあまり得意ではないため、ヒープを使用して参照型を格納します。これは、メモリが周囲の他のオブジェクトに関係なく割り当てられ、割り当て解除される場所です。

    ボクシングとアンボクシングの場合:

    ボクシング(ラッピングとも呼ばれます)は、プリミティブ型のオブジェクトを取得し、それを参照型として格納するプロセスです(つまり、にfloat xなりますFloat x)。これにより、これら2つのオブジェクトは同じ型になります。(クリスマスプレゼントを紙で包むようなものです)つまり、舞台裏でInteger k = 6は、一種のボクシング(オートボクシング)です。

    一方、開梱は開開の反対であるため、開梱と呼ぶことができます。Unboxingは、「ボックス化された」オブジェクトを取得し、それを参照型からプリミティブ型に戻すため、ステートメントはそれほど面倒なことなく機能します。

    Integer k = 6; //Boxing

    int m = k; //Unboxing

    あなたの質問に関して、これが実際に何を意味するのか:あなたが投稿したコードで、自動ボックス化とアンボックス化が発生し、ステートメントが有効になりました。JVMは、意図したとおりに実行できるほど賢いものでしたが、ボックス化とボックス化解除がコードのパフォーマンスに深刻な影響を与える可能性があるため、JVMを定期的に使用する必要があるという意味ではありません。

    また、とが両方ともタイプの場合、x参照yFloat比較することになります。

    幸運を!

于 2012-10-25T15:16:31.323 に答える