2009-11-07 8 views
9

新しいエンジニアのトレーニングだけでなく、Jon Skeet's DevDays presentationを読むことに従事した後、多くのエンジニアがいつどの数値データ型を使用するか明確ではないことを認識し始めました。正式なコンピュータサイエンスの学位がこれを手助けする役に感謝しますが、大規模なデータセットや金融ソフトウェア、フィキシスや統計の問題や複雑なデータストアの問題を扱ったことがないため、多くの新しいエンジニアが不確実性を感じています。正しい数値データ型を使用する

私の経験では、人々は実際に文脈の中で説明されているときには概念をgrokしています。私は、特定のデータがデータ型を使用して最もよく表現される実際のプログラミング問題の良い例を探しています。可能であれば、教科書の例から離れてください。私は、Javaでこれをタグ付け、他の言語での例や再タグ付けを与えること自由に感じています:それは維持に来るとき

答えて

26

私は本当にあなたが複雑な例や何かを必要としないと思います。これは簡単です:

  • それは整数ですか?
    • > 2^63ですか? BigInteger
    • 2^31を超えることはできますか?長い
    • それ以外の場合はint
  • 10進数ですか?
    • おおよその値は?
      • ダブル
    • それが正確である必要がありますか? (例:金額!)
      • のBigDecimal

(私は、私はもちろん、 "絶対値の大きい" 意味 ">" と言うとき。)私はバイトや文字を使って数字を表したことは一度もありませんでした。それは12年間のJavaプログラミングにあります。浮く? Meh。あなたが巨大な配列を持っていて、あなたが記憶上の問題を抱えているなら、私は推測します。

BigDecimalの名前は多少間違っています。あなたの価値はではありません。はそれを必要とするためには大きくなければなりません。

+4

私は本当にあなたがそれを打破した方法が好きです。 100%がchar、short、Javaで浮動小数点数にあなたに同意します。 – Scanningcrew

+0

もう1つのヒント:10進数で正確である必要があるが、事前に($ values:2 dec。placesなどの)小数点以下の桁数がわかっている場合は、int/outputに分割します。これにより、BitDecimal(パフォーマンス、扱いにくい演算子)の問題が回避されます。 – sleske

4

BigDecimalのがベストです...

整数、ロング、ダブル、フロート、BigIntegerの、など正確な浮動小数点計算、および所望の精度を指定することができる。私は浮動小数点(およびある程度倍精度浮動小数点)がBigDecimalよりもパフォーマンスの利点を提供すると信じていますが、精度とユーザビリティを犠牲にしています。

+0

+1この回答を投票したばか人に対抗するには – kar

+0

LOL、ありがとう! –

1

正常数値我々は、機械independenat(32/64ビット)データ型のサイズを話している場合、以下のように

整数である:4バイト

長:8バイト

小数/フロート:4バイト

ダブル:8バイト

および署名された値の半分に減少サイズ(例:4バイト、符号なし= 4billionsため、=の2billionsを締結)

bigInt(言語実装によります)時には10バイトまでです。

大容量データアーカイブ(検索エンジンなど)の場合は、スペースを節約するためにバイトとショートを強くお勧めします。

バイト:1バイト、(0-256符号なし、-128 - 128は、符号付き)

短い:2バイト(65K符号なし)


あなたはAGEについての記録を保存したいとしましょう、誰も150を超えて生きていないので、データ型BYTEを使用しました(上記のサイズを読んでください)。しかし、INTEGERを使用すると、余分な3bytesを無駄にしてしまいました。

+1

早期最適化の古典的な例...大規模な配列やデータベースを保存していない限り、人口の年齢はUSE INTです。サイズが問題ではない場合(そして現代ではそうではない場合)には欠点はなく、時期尚早の最適化のためにY2Kバグのような愚かなバグに祈ってはいけません。 –

+0

私は生年月日ではなく、年齢について話していました。私が作成したトピックを見てみると、私はカスタムWebスケールの検索エンジン(高度に最適化されたインデックスフォーマット)をほぼ2年間開発していて、ディスクインデックスの最適化には大いに役立ちます。私はスペースを節約し、Y2K制限を避けるために、INT(32)とLONG(64)の両方を日付として使用します。 – kar

+0

また、FYI sawasでは、私たちのデータの一部を3バイトと5バイトに保存し、通常の4/8バイトでメモリスペースにロードして、ロード時に余分な速度を得るためにVInt(lucene)だから私は何を話しているのか知っている。 – kar

4

明示する必要がある重要な点の1つは、浮動小数点数を比較することはほとんど常に誤りであるということです。たとえば、次のコードは失敗する可能性が非常に高いです。

double euros = convertToEuros(item.getCostInDollars()); 
if (euros == 10.0) { 
    // this line will most likely never be reached 
} 

これは、離散的な数字を使用して通貨を表す理由の1つです。

絶対に浮動小数点数を比較する必要がある場合は、そのようにすることができます。範囲に何か:

  • ダブル:

    実用的な例については
    double euros = convertToEuros(item.getCostInDollars()); 
    if (Math.abs(euros - 10.0) < EPSILON) { 
        // this might work 
    } 
    

    、親指の私の通常のルールは、このようなもので、それを使用する前に長いとハードだと思います。それにふさわしい痛みはありますか?

  • フロート:それを
  • バイトを使用していない:最も頻繁にバイトとして使用すると、[]いくつかの生のバイナリデータを表現するために
  • INT:これはあなたの親友です。
  • long:これをタイムスタンプとデータベースIDに使用してください
  • BigDecimalとBigInteger:これらについて知っていれば、あなたはすでに何をしているのか知っていますので、私のアドバイスは必要ありません

私は、これらは科学的な大雑把なルールではないことを認識していますが、ターゲットオーディエンスがコンピューターサイエンティストでない場合は、基本に固執するのが最善の方法です。

+0

私はあなたのサンプルコードの大ファンではありません。なぜなら、金銭的なデータを最初に二重に使うべきではないからです。 BigDecimalを使うべきです。例えば、これは:http://stackoverflow.com/questions/965831/how-to-parse-a-currency-amount-us-or-eu-to-float-value-in-java/965858#965858およびbook Effective Java(第2版) – Jonik

+2

Jonik - 彼は二重悪い理由を私たちに示しています。そして、「浮動小数点を絶対に使用する必要がある場合は、*ここでそれを行う方法はここにあります」と彼は言う。ここにはファウルはない。 –

+0

btw、これは優れた答えだと思います。唯一の例外は、BigDecimalが10進数を正確に処理する唯一の方法として強く求められるべきことです。単に "ああ、あなたはおそらくあなたが何をしているか知っているだけではない"。 –

1

VInt's Luceneは悪魔です。小さなメリットは、バイトごとに読み込む際のパフォーマンス上の不利益よりもはるかに重要です。

良いことは、スペースと時間のトレードオフです。 1996年には200MBを節約しましたが、2010年に一度に1バイトずつ読み込むIOバッファを駄目にすることはひどいことです。

関連する問題