'uint'および 'short'データ型が標準のint(32)よりも適切な場合はどれですか?


24

能力と価値観の違いを理解できますが、それが適切かどうかに関係なく、常に使用しているように見えInt32ます。uint多くの場合、負にならない値(データベースレコードのIDを表すなど)を記述するため、より適切な場合でも、署名なしバージョン()を使用することはありません。また、short/Int16値の必要な容量に関係なく、誰も使用していないようです。

客観的に、それが使用することをお勧めします場合があることuintshort/Int16、彼らであり、そうであれば、?


13
人気は、常にソフトウェア設計の決定を評価するための実行可能な指標ではありません。プラクティスが人気があるからといって、それが特定のアプリケーションに適切なプラクティスであることや、それが良いプラクティスであることを意味するわけではありません。
ロバートハーベイ14


1
簡単な答えは、プログラマは署名されたセマンティクスに慣れており、署名されていない型(したがって、署名されていないセマンティクス)を扱う場合でも、それらを想定する傾向があるということです。ほとんどの人は、プログラマーが怠けているか、教育を受けていないことだと思っていますが、問題のプログラマーは実際、非常に教育されていて非常に慎重であり、微妙な落とし穴を避けたいと考えています。必要に応じてsoundsoftware.ac.uk / c-pitfall- unsignedおよびanteru.net/2010/05/17/736をご覧ください
テオドロスチャツィジアンナキス14

符号なしの数値では、符号はnull正または負を超えています。ネガティブにならない、または常にポジティブであると考えると、結果に驚きます(そしてしばしば怒ります)。署名された値から。
アダムD.

1
私の経験では、C言語でプログラミングしたことのある多くのプログラマーは、GBのメモリとストレージスペースのバイトを気にする傾向があります。
user1451111

回答:


25

あなたは、あなたがあなた自身の経験によって色付けされた視点を参照しているのではないかと疑っています。これはよくあることかもしれませんが、人々がよくそれらを正しく使用するのは私の経験です。

利点は、メモリ空間とCPU時間です。タイプがワイヤ経由で送信されるか、ディスクに送信されるかによって、IO空間も場合によって異なります。符号なしの型は、不可能な特定の操作を行わないことを確認するコンパイラーチェックを提供し、さらに必要な場合にパフォーマンスを向上させるために使用可能な範囲を拡張しながらサイズを小さくします。

正しい使用は、あなたが期待するようです-あなたが知っている、いつでも特定のためには、あなたがそれらを使用することができます恒久的に(確実性なしに拘束していないか、あなたがなり、後でそれを後悔します)。

  • 決して合理的に負になり得ない何か(public uint NumberOfPeople)を表現しようとしている場合は、符号なしの型を使用してください。
  • 合理的に255(public byte DamagedToothCount)より大きくなることのないものを表現しようとしている場合は、バイトを使用します。
  • 合理的に255を超える可能性があるものを表現しようとしているが、数千を超えることはない場合は、short(public short JimmyHoffasBankBalance)を使用します。
  • 数十万、数百万であっても数十億に達する可能性が低いものを表現しようとしている場合は、int(public int HoursSinceUnixEpoch)を使用します。
  • 確かにこの数が無限に大きい値を持っているかもしれないか、それが数十億を持っているかもしれないと思うが、何十億を確信していないなら、あなたの最善の策は長いです。長さが足りない場合、興味深い問題が発生し、任意の精度の数値(public long MyReallyGreatAppsUserCountThisIsNotWishfulThinkingAtAll)を確認する必要があります。

この推論は、符号付き、符号なし、さまざまなサイズなどのタイプを選択する際に使用できます。実際に表現しているデータの論理的真実について考えてください。


11
+1。電話の「数字」は数字ではなく数字のストリングであり、オプションでフォーマットされていることを明確にする必要があります。あなたはこれに気づいているように見えますが、私たちは悪い例を設定したくありません。また、値の範囲をarbitrarily意的に制限することは近視眼的なアンチパターンintです。問題のドメインが実際に値を制限しているという事実を知らない限り、どこでも銀行は口座を33Kクイッドにハード制限したいとは思いません。それがあふれたら…!)。
アモン14

3
新しいライフゴール:銀行口座の不可欠なタイプをアンダーフローさせる、かなりの量のオーバードラフト。
recursion.ninja 14

11
たとえば、算術が符号付きと符号なしの間で混在している場合など、特定の場所で符号なしの型を使用しない理由があります。符号なし整数に関するベストプラクティスは何ですか?をご覧ください

19
ここでの論拠には同意しません。符号なしの型は、intに慣れていると予期せぬ減算や比較が行われるため、しばしば間違いです(一貫した方法で動作しますが、「常に正」ではありません)。あなたがそれらを使用する非常に特定の理由がない限り、私はそれらを避けるでしょう。また、バイト対ショート対整数でサイズが重要なのはなぜですか?構造体はこれらのメンバーまたは配列を特定の配置にパディングするため、多くの場合、スペースさえ節約しません。サイズが本当に重要な場合(特に私が見たC#コードとは異なり)、または何かのために特に255でラップアラウンドしたい場合にのみ、バイトを使用します。
アダムD.ラッペ14

4
「利点はメモリ空間とCPU時間です」... 小さなタイプが実際にCPU時間を節約するケースは見当たりません。整数演算は、マシンサイズのタイプよりも速くなることはありませんlong。つまり、CPUに関する限り、を使用してもかまいません。もちろん、メモリの節約はキャッシュラインの効率の改善などにより間接的に時間を節約できますが、OTOHの小さなタイプのアライメントの問題は間接的に時間を消費します。
leftaroundabout 14

16

もちろん、uintまたはshortまたはを使用した方が良い場合がありますInt16。データ範囲がその変数タイプの制約内に収まることがわかっている場合は、そのタイプを使用してもかまいませ

メモリが制限された環境で、または大量のオブジェクトを処理する場合、最小サイズの変数を使用することは理にかなっています。たとえば、ints とsの100万個の要素配列のサイズには大きな違いがありshortます。

多くの場合、次の1つ以上の理由により、実際のコードでは発生しません。

  • データの制約は事前に知られていない
  • データの制約がしっかりしていないか、変更される可能性が高いことがわかっている可能性がありました
  • より広いデータ範囲で関数を再利用する希望がありました
  • 開発者は制約を考えるのに時間をかけませんでした
  • メモリの節約は、より小さな変数タイプを使用することを正当化するほど重要ではありませんでした

考えられる理由は他にもたくさんありますが、要約すると次のとおりです 。異なる変数タイプを決定して使用するのにかかる時間は、そうすることを正当化するのに十分な利点を提供しませんでした。


8

Cでは、整数の昇格を伴わないコンテキストで、符号なしの値が「ラッピング」抽象代数リングのメンバーとして動作するように指定されました(したがって、XおよびYについて、XYは一意の値を生成し、Yに追加されるとXを生成します) )、符号付き整数型は、計算が特定の範囲内にとどまると整数のように動作するように指定され、計算がそれを超えた場合は何でもできるようになりました。ただし、C#の数値セマンティクスはまったく異なります。チェックされた数値コンテキスト内の場合、符号付き型と符号なし型の両方は、計算が範囲内にあるOverflowException場合は整数のように動作し、そうでない場合はスローします。チェックされていないコンテキストでは、両方とも代数リングのように動作します。

一般にInt32、コンパクトなストレージまたはトランスポートのために物を梱包または開梱する必要がある場合よりも小さいデータ型を使用する価値があるのは唯一の時間です。5億の正数を格納する必要があり、それらがすべて0〜100の範囲にある場合、4つではなくそれぞれ1バイトを使用すると、1.5ギガバイトのストレージが節約されます。それは大きな節約です。ただし、コードの一部に合計数百の値を格納する必要がある場合、それぞれを4つではなく1バイトにすると、約600バイト節約できます。おそらく気にする価値はありません。

符号なしの型に関して、それらが本当に役立つのは、情報交換を実行するとき、または数字を断片に分割するときだけです。たとえば、96ビット整数で計算する必要がある場合、符号付き整数のグループよりも、3つの符号なし32ビット整数のグループで計算を実行する方がはるかに簡単です。そうでない場合、符号付き32ビットまたは64ビット値の範囲が不十分になる状況はあまり多くありませんが、同じサイズの符号なし値で十分です。


4

一般に、符号なしの型は不快な方法でオーバーフローするため、使用しないことをお勧めします。x = 5-6突然コードのタイムボムになります。一方、符号なしの型の利点は精度が1ビット余分に低下するため、そのビットで十分であれば、代わりに大きな型を使用する必要があります。

小さい型が理にかなっているユースケースがありますが、メモリ使用量を心配したり、伝送やキャッシュの効率のためにデータをパックする必要がある場合、または他のいくつかの懸念がある場合を除き、通常、小さい型を使用するメリットはありません。さらに、多くのアーキテクチャでは、実際にこれらのタイプを使用する方が遅いため、実際に少額のコストを課すことができます。


3
Cでは、符号付きオーバーフローは符号なしオーバーフローよりもさらに悪化します(未定義の動作であるため、符号なしは走行距離計のようにロールオーバーするように指定されています)。OTOH、符号付きのオーバーフロー/アンダーフローは、実際には符号なしのアンダーフローよりもはるかに一般的ではありません。
ケビン14

本当ですが、通常、符号付きオーバーフローはより明白で予測可能です。
ジャックエイドリー14

私は一般的に同意しますが、例えば、最新のコンパイラーは署名さi+1>iれている1場合に最適化されi、他の厄介な動作のホスト全体に最適化される可能性があることに注意する必要があります。符号なしオーバーフローは、コーナーケースでバグを引き起こす可能性があります。符号付きオーバーフローは、プログラム全体を無意味にする可能性があります
ケビン14

@JackAidley 5-6が同じビットパターンを生成するので、あなたが言うことは意味がないと確信しています。
インゴ14

@Ingo:どのくらいの頻度でビットパターンを見ますか?重要なのは、ビットがオンかオフかではなく、ビットパターンの意味です。
ジャックエイドリー14

2

CLSコンプライアンスは、.NETタイプを具体的に扱うときに忘れられがちで、おそらくあなたの質問に正接する場合があります。.NET Framework上に構築されたすべての言語ですべてのタイプが利用できるわけではありません。

C#以外の言語で使用されるコードを記述していて、そのコードができるだけ多くの.NET言語と相互運用できることを保証したい場合は、CLS準拠の型の使用を制限する必要があります。

たとえば、VB.NETの初期バージョン(7.0および7.1)は、符号なし整数(UInteger)をサポートしていませんでした。

http://msdn.microsoft.com/en-us/library/aa903459(v=vs.71).aspx

符号なし整数はCLSに準拠していないため、クラスライブラリの消費者が誰なのかわからない場合は注意して使用する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.