2012-04-30 18 views
3

私は以下のコードを持っていることがあります。0より大きいか0より小さい浮動小数点

何が原因でさまざまな結果が生じるのでしょうか?

0.00文字列はJSONオブジェクトに由来します。

(コード簡体字)

if(new Float("0.00")>0){ 
    // do something 
} 

EDIT:

私は何を持っていることは、私はそのゼロ、ゼロより小さいかゼロ以上かどうかを判断したいいくつかの浮動小数点数です。値は、0.00,0.001または-0.001のようなものかもしれません。彼らが肯定的、否定的、または零であるかどうかをどのように判断するのですか?

編集:

多分私は値をどのように得るべきかを明確にする必要があります。私はBigDecimalについて読んで、役に立たないようにしようとしたので、問題を引き起こしているまったく別のものかもしれません。このコード使用:

値は(0.000この形式のLTを有する):JSONフィードから抽出された価格がゼロより大きいか小さいかどうかをテストするためにそして

price = new BigDecimal(stocksJSONArray.getJSONObject(i).getString("LT")); 

を、私は、次の条件文を使用しました:

if(price.compareTo(BigDecimal.ZERO)==1){ 
    // greater than zero 
} 
else if(price.compareTo(BigDecimal.ZERO)==-1){ 
    // less than zero 
} 

このコードは、JSONフィードから読み込まれた多くの値についてループされています。そして結果から、ゼロであるpriceの一部はゼロより大きく処理され、一部はゼロより小さく処理されます。私は他の何かがここで問題を引き起こしていると疑っていますか?

また、データの精度に問題があるかどうかをテストしました。だから私はこのでした:

DecimalFormat frmt = new DecimalFormat("0.000000000000000000000000"); 
String formatted = frmt.format(stock.change); 

をそして陽性とネガとして認識してしまったゼロのために、それのためのトレース値はまだ0.000000000000000000000000、ない0.000000000000000000000001またはそのような何かでした。

+0

この回答は正しいものの、結果は変わるものではありません。 '0.00'は常にそのまま解析されますか?そして、浮動小数点値が初期化される値が、他の浮動小数点演算の結果ではないことは確かですか? – Jack

+1

詳細については、「浮動小数点演算についての各コンピュータ科学者の知るべきこと」(http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)を参照してください。私が言っていたことのほとんどが間違っていたので、私は私の答えを削除しました。この問題にはるかに熟練した人々がいる。 –

答えて

3

あなたの表現が確実にJavaでfalseの結果を生成します。

ただし、ゼロは、たとえば、-1を正の無限大で除算した結果であるとします。この場合、内部的には-0.00と表示されます。場合によっては、ゼロ(マイナス記号なし)として印刷されますが、それ以外の場合は0.00とは異なる動作をします。

一般的に浮動小数点数は、整数と同じ方法で比較することができます - 丸め誤差の危険性がありますが、ランダムな小さな値を加算または減算することによってその誤差は助けられません。それは平等のために比較して異なっている。

浮動小数点の動作については、事実とdo more readingを再確認することをお勧めします。

を編集します。元の質問に答えるために上記の作業を大幅に簡素化しています。質問の編集に答えるには、もっと深くする必要があります。

について

つの入力精度精度を知っていると考えるべきである浮動小数点数、及び出力の所望の精度上の任意の操作。時には課題が解決できないこともありますが、入力精度が答えを出すには不十分であることもあります。

の精度は32ビットです。そのうち24ビットは仮数で、8ビットの指数です。つまり、このデータ型は安全に0.001 0.001000001から0.00100001からではなく、あなたが簡単に見ることができるように区別することを意味します。

System.out.println((float)0.001 < (float)0.001000001); 

(あなたはキャストによって単精度の比較を強制しなかった場合は、異なる結果を得ることに注意してくださいにその場合、計算は倍精度で行われ、数値は安全に区別されます。それらをさらに近づけるまで)

したがって、精度はデータ型によって決まります。それほど正確ではない。入力精度は、精度が精度より優れていることを除いて、データ型とは関係がないため、精度よりも決定が難しい場合がよくあります。

数学的実数は、特定の浮動小数点型の表現能力に関して4つの可能な状況にあり、それが人間が判読可能な10進表記でリテラルとして発生したときに受け取るさまざまな処理に対応します。

  • バイナリで正確に表現できます。たとえば、0または0.25です。それで、それは整数が整数変数になるほど正確です。
  • または、精度がタイプの精度に対応しておおよそ表現可能です。例えば1/3または0.1または0.001である。これは、指数が必要な指数ビットの数に合っているが、数値の2進展開が仮数よりも長く、または完全に無限大の場合に発生します。
  • またはそれは大幅に歪んだ精度でほぼ表現できます。これらはdenormal(非正規)です。それが不正確であるだけでなく、その上の算術演算がクロールまで遅くなる可能性があります。通常は正しく動作することが証明されています。この種のリテラルを見ても尊敬できるJavaコンパイラが少し汗をかいているかもしれませんが、それはbugです。
  • これはまったく合わないので、コンパイラはリテラルを大きすぎると拒否します。

あなたのケースでは、0(正確)、0.001(近似)、-0.001(近似)の3つの有効な入力があり、問題が解決します。 数値を0リテラル(正確なところであります)と比較すると、は常に期待されるブール値(完全に正確な出力)を得ることができます。

これは、リテラルから直接派生した入力によって異なります。あなたの入力が0.001、-0。001と(float)1000 * (float)0.001 - 1、これは別の質問だろうとあなたは答えを取得する必要があります、このような例:

if (-0.00001 < x && x < 0.00001) // then x is zero 

そして、あなたは一切の入力だけでなく、これらの3つの魔法の値を許可し、見当もつかない場合入力の正確さについては、それはただの使命ではありません。 0.000000000...として始まるリテラルでさえ、最後にはいくらかガベージディジットが残っていても、Javaコンパイラによって完全にニュートラルなゼロに変換されます。この後、Javaコードは正確で美しい0.00アンダーフロー値にマイナス記号を追加するとどうなりますか。変数は3つの異なる値ではなく、すべて同じ、不正確なゼロ、同じビットパターンです。

+0

私は、私の答えをコメントにダウングレードすることを決めました。あなたのより重視される答えに+1してください。 :) –

+0

@AndrewThompson - 私は(私は熱心な浮動小数点avoiderです)と、あなたが提供する強力なナンセンスリファレンスの価値があるとは思わないあなたの身振りのおかげで。鉱山はむしろチートシートです。 –

+0

*「チートシート」*私はそのようなことを評価します。彼らは基本的な問題の大半を解決することができます。 :) –

1

フロートが不正確です。あなたは次のように、誤差の範囲を指定する必要があります。

float result = new Float("0.00"); 
float expected = 0; 
if (Math.abs(result - expected) < 0.00001) 
... 
0

Math.signum()を使用して、値が0かそれより小さいかどうかを確認できます。

0

私は少し違いました。私はセンサーが1の読みを示すことを期待していました。これが私が思いついたものです。

double a = y1; 
       if((a-0)<1){ 
        a=(1-a)+a; 
       } 
関連する問題