uint vsintの使用[クローズ]


83

私はしばらくの間、C#プログラマーはどこでもintを使用する傾向があり、uintに頼ることはめったにないことを観察しました。しかし、私はその理由について満足のいく答えを見つけたことがありません。

相互運用性が目標である場合、すべてのCLI言語が符号なし整数をサポートしているわけではないため、uintをパブリックAPIに表示しないでください。しかし、それは、内部クラスでさえ、intがそれほど普及している理由を説明していません。これが、uintがBCLで控えめに使用されている理由だと思います。

C ++では、負の値が意味をなさない整数がある場合は、符号なし整数を選択します。

これは、負の数が許可または予期されていないことを明確に示しており、コンパイラがチェックを行います。また、配列インデックスの場合、JITが下限チェックを簡単に削除できるのではないかと思います。

ただし、intタイプとunitタイプを混在させる場合は、特別な注意とキャストが必要になります。

uintをもっと使うべきですか?どうして?



私は既視感を持っていると思っただけです:D、ほぼ正確に同じ質問が少し前に尋ねられました。
KroaX 2010年

下限チェック用として、あなた置き換えることができます(場合には、あなた自身を記述する必要があります)if (i < 0 || i >= length)if (unchecked((uint)i) >= length)。結果として得られるILは、合計で1つの(分岐)命令が少なくなり、ほぼ同じパフォーマンス(非常に高速)になります。個人的には、それが下限をチェックすることに対して私のかゆみを掻くという理由だけでそれが大好きです。他の人は「チェックされていない」ためにそれに反対する可能性がありますが、これはその意味を学ぶための非常に良い行であると私は主張します。
AnorZaken 2015

上記は64ビットとの比較を実行するため、64ビットビルドで最適であることを忘れてしまいました。32ビットビルドの場合、if (unchecked((uint)i) >= unchecked((uint)length))パフォーマンスが向上します。ただし、これは非常に複雑に見えます。64ビットの比較は、標準の二重分岐境界よりもパフォーマンスが優れています。32ビットビルドで確認するため、合理的な状況ではこれをお勧めできません。(64ビットの比較が他の方法で使用されていることを指摘するために主に言及しています-これは一部の人にとって有用な情報かもしれません。)
AnorZaken 2015

紳士、私はあなたの主要な意見ベースは良くないと主張します。客観的な答えがあれば、私も聞いてみたいと思います。私はすべて、利益のために自分の慣行を変えることに賛成です。
ジョシュア

回答:


50

なぜuintBCLで使用されないのかについてのあなたの観察が、主な理由だと私は思う。

UInt32はCLSに準拠していません。つまり、パブリックAPIでの使用にはまったく不適切です。プライベートAPIでuintを使用する場合、これは他のタイプへの変換を行うことを意味します。通常、タイプを同じに保つ方が簡単で安全です。

また、主にBCLで一般的ではないため、C#が使用されている唯一の言語である場合でも、これはC#開発では一般的ではないと思います。一般に、開発者は(ありがたいことに)構築しているフレームワークのスタイルを模倣しようとします。C#の場合、これは、パブリックおよび内部のAPIを可能な限り.NET FrameworkBCLのように見せようとすることを意味します。これは、uintを控えめに使用することを意味します。


1
stackoverflow.com/questions/2013116/…は同様のトピックを扱う質問です
Stephan

77

intタイプするのはuint。より短いです。


2
これはかなり真実に近いと思います。uint(私の経験では)99%の時間でint十分なのになぜ使用するのですか?
マシュージョーンズ

12
@ジャスティン:一般的に、-1のような「マジックナンバー」は良い考えではありません。longに切り替えるということは、理由もなく2xメモリを使用することも意味します...他のAPIと対話する必要がない限り、「ユニット」は間違いなく価値があります。
リードコプシー2010年

28
int負のインデックスを作成することは決してないので、配列のインデックスを作成するためにを使用することに慣れることはありません。uintこの場合、aを使用する必要があることはやみくもに明らかなようです。
マークH

2
言うまでもなく、より読みやすくなります。あなたが他の誰かに読ませるためにあなたよりも経験が浅いかもしれないあなたのコード/アルゴリズムを渡した場合、たくさん使うことはuintそれらを少しハングアップさせる可能性があります。intあなたがそれが取る範囲を制御するすべての状況で使用するのに完全に受け入れられます。
drharris 2010年

3
@MarkH完全に同意しましたが、逆反復を行う場合は、次の形式で役立ちますfor (int i = arr.Length - 1; i >= 0; i--) { }。uintを使用してこれを行うと、オーバーフロー例外が発生するか、さらに悪いことに、無限ループが発生します。
aidiakapi 2014年

19

通常intは十分です。次のすべての条件を満たすことができる場合は、次を使用できますuint

  • パブリックAPI用ではありません(uintCLSに準拠していないため)。
  • 負の数は必要ありません。
  • 追加の範囲が必要になる場合があります。
  • あなたはされていないと比較して、それを使用して< 0いるが、決してありませんよう、true
  • あなたはされていないと比較して、それを使用して>= 0いるが、決してありませんよう、false

最後の要件はしばしば忘れられ、バグが発生します。

static void Main(string[] args)
{
    if (args.Length == 0) return;
    uint last = (uint)(args.Length - 1);

    // This will eventually throw an IndexOutOfRangeException:
    for (uint i = last; i >= 0; i--)
    {
        Console.WriteLine(args[i]);
    }
}

13

1)悪い習慣。真剣に。C / C ++でも。

一般的なforパターンを考えてみてください。

for( int i=0; i<3; i++ )
    foo(i);

そこで整数を使用する理由はまったくありません。負の値になることはありません。しかし、(少なくとも)他の2つの「スタイル」エラーが含まれている場合でも、ほとんどすべての人がそのように単純なループを実行します。

2)intマシンのネイティブタイプとして認識されます。


4

負の数が実際に許容値の範囲内uintintない限り、私は好みます。特に、intパラメータを受け入れてArgumentExceptionも、数値がゼロ未満の場合にをスローするのはばかげていますuint。!を使用してください。

私はそれuintが十分に活用されていないことに同意し、他のすべての人にそれをもっと使うことを勧めます。


7
uintのみを受け入れ、境界をチェックしないことは非常に危険です。誰かが負の値を渡すと、CLRはそれを大きなintとして解釈します。つまり、-1の場合はuint.maxvalueを取得します。これは望ましくない動作です。
アンリ

19
@Henri:C#にはintからuintへの暗黙の変換がないため、「誰かが負の値を渡した場合」はありません。もちろん、上限の境界チェックは依然として適切です(ただし、今では2つではなく1つのチェックのみが必要です)。
Ben Voigt 2010年

1

私はintが100を超えることはめったにない低レベルのアプリケーション層でプログラミングしているので、負の値は問題ではありません(たとえば、i <myname.length()タイプのもの)。これは古いCの習慣であり、上記のようにタイプするのが短くなります。ただし、場合によっては、デバイスからのイベントフラグを処理しているハードウェアに接続するときに、フラグが左(最上位)のビットを使用する可能性がある場合にuintが重要になります。

正直なところ、私の仕事の99.9%で、ushortを簡単に使用できましたが、intは、ushortよりもはるかに優れたサウンドです。


1

C#でDirect3D 10ラッパーを作成しました。非常に大きな頂点バッファーを作成する場合は、uintを使用する必要があります。ビデオカードの大きなバッファは、signedintで表すことはできません。

UINTは非常に便利で、他のことを言うのはばかげています。誰もuintを使用する必要がなかったという理由だけで誰かが考えるなら、あなたは間違っています。


これは、より広い範囲を利用できる良いケースです。
レオ・ガーディアン2017年

0

ただの怠惰だと思います。C#は本質的に、比較的多くのリソースを備えたデスクトップやその他のマシンでの開発に最適です。

ただし、CおよびC ++は、メモリが少ない古いシステムや組み込みシステムに深く根ざしているため、プログラマーは使用するデータ型を慎重に検討することに慣れています。C#プログラマーは怠惰であり、一般に十分なリソースがあるため、メモリ使用量を実際に最適化する人は誰もいません(一般的に、もちろん常にではありません)。1バイトで十分な場合、私を含む多くのC#プログラマーは、単純化のためにintを使用します。さらに、多くのAPI関数はintを受け入れるため、キャストを防ぎます。

正しいデータ型を選択することは良い習慣であることに同意しますが、主な動機は怠惰だと思います。

最後に、整数を選択する方が数学的に正しいです。符号なし整数は数学には存在しません(自然数のみ)。また、ほとんどのプログラマーは数学的なバックグラウンドを持っているため、整数を使用する方が自然です。


怠惰にはメリットがありますが、怠惰とは言えません。ほとんどの場合、私はint / uintのことを十分に気にせず、そのような決定に脳のサイクルを浪費し、intを使用するだけです。ハードウェアは安価であり、プログラマーは高価になる可能性があります。
SWeko 2010年

プログラマーは怠け者です。それは悪いことです。レイモンドは、プログラマーは税金を払うのが嫌いだと言うでしょう!
lornova 2010年

私たちC#プログラマーが怠け者であることを最初に管理するのは私ですが、それは必ずしも悪いことではありません。
ChaosPandion 2010年

@Lorenzo、私は大学で、怠惰なプログラマーは優れたプログラマーであると述べた記事を書きました。ほとんどの場合、それはマシン時間ではなくプログラマー時間の最適化に関するものでした。
Eloff 2010年

1
うーん、...怠惰によって引き起こされる、私が今まで見た(あるいは行なわ)きプログラマ-imputableバグのほとんど
lornova

0

その理由の大部分は、Cが最初に出たときint、簡潔にするために使用された例のほとんどがあったことだと思います。私たちはintegerFortranやPascalのように書く必要がないことに喜びを感じ、当時は配列インデックスやループカウンターなどのありふれたものに日常的に使用していました。符号なし整数は、最後の余分なビットを必要とする大きな数の特殊なケースでした。Cの習慣がC#やPythonのような他の新しい言語に続いたのは自然な流れだと思います。


0

一部の言語(Pascalの多くのバージョンなど)では、符号なしの型を数値を表すものと見なしています。符号なし型と同じサイズの符号付き型の間の演算は、通常、オペランドが次に大きい型にプロモートされたかのように実行されます(一部の言語では、最大の型に符号なしの同等物がないため、このようなプロモートは常に可能です。 )。

他の言語(Cなど)は、Nビットの符号なし型を2 ^ Nを法としてラップアラウンドするグループと見なします。このようなグループのメンバーからNを減算することは、数値の減算を表すのではなく、グループメンバーを生成し、Nを加算すると、元のメンバーが生成されることに注意してください。間違いなく、符号付きと符号なしの値の混合を含む特定の操作は実際には意味がなく、おそらく禁止されるべきでしたが、数値リテラルなどの仕様がずさんなコードでも通常は機能し、符号付きを混合するコードが記述されています符号なしの型であり、ずさんなものであるにもかかわらず、仕様がすぐに変更されることはありません。

符号付きタイプと符号なしタイプの間の相互作用のすべての複雑さを解決するよりも、符号付きタイプのみを使用する方がはるかに簡単です。符号なし型は、小さな断片から大きな数を分解する場合(シリアル化など)、またはそのような数を再構成する場合に役立ちますが、一般に、実際に数量を表すものには符号付き数を使用する方が適切です。


0

これはおそらく古いスレッドだと思いますが、いくつか説明したいと思います。

–128〜127を格納できるint8を考えてみましょう。これは、合計127の正の数である1バイトを使用します。
int8を使用する場合、ビットの1つが負の数-128に使用されます。
Uint8を使用する場合は、正の数に負の数を指定するため、1バイトの同じ容量のストレージで255の正の数を使用できます。
唯一の欠点は、負の値を使用する機能が失われたことです。
これに関する別の問題は、すべてのプログラミング言語とデータベースがこれをサポートしているわけではないということです。
私の意見では、これを使用する唯一の理由は、ゲームプログラミングのように効率的である必要があり、負でない大きな数値を格納する必要がある場合です。これが、多くのプログラムがこれを使用しない理由です。

主な理由は、ストレージが問題ではなく、他のソフトウェア、プラグイン、データベース、またはApiで柔軟に使用できないことです。また、たとえば、銀行はお金などを保管するために負の数を必要とします。

これが誰かの助けになることを願っています。

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