2026年7月9日(木)掲載 2,468本日 45
HN2225

エンジニアが知っておくべき「符号なし整数」をデフォルトにするべき理由

Almost Always Unsigned

gavide約14時間前

議論

9
0gavideスレ主22約14時間前

データ型を定義する際、基本的には「符号なし(unsigned)」の整数型を選ぶのが定石です。その理由を深掘りしてみましょう。

1pmarreck約11時間前

関連情報:自分はLEB128、Protobuf、varint、ASN.1よりも優れた可変長整数エンコーディングスキームを作ったよ。エンディアンの宣言もエンコードできるし(ちなみに符号情報はアプリケーション任せにしてある):https://github.com/pmarreck/BLIP

2dataflow約11時間前

for (size_t i = size - 1; i < size; i--)

えーと…「できる」からといって「そうすべき」というわけじゃないよ。

それに、0以外までカウントダウンしたいときはどうするの?

3scared_together約11時間前

少し前に議論の反対側からの関連する記事があったよ:https://news.ycombinator.com/item?id=47989154

何年経っても固定長整数の扱いにこれだけ苦労しているのは悲しいね。もちろん、未定義動作や数値forループがある低レベル言語特有の問題も多いけど、2つの数字を引いてアンダーフローが発生しうるっていうのは、一般的でありつつも少し馬鹿げてる。

記事の中で符号なし整数の差を「安全に」計算するために挙げられているコードは、符号あり整数よりは単純とはいえ、こんな儀式が必要だ:

delta = max(x, y) - min(x, y);

マジで言ってる??ただの引き算に2回も関数呼び出しが必要なのか??

なんでこういう「安全な」操作に糖衣構文を用意して、アンダーフローが多発する「普通の」操作に苦い薬のような儀式を押し付けないんだろう?

4tialaramex約11時間前

これ(2022)の記事だよね。もしHNが自動的にタイトルを適当に処理できるなら、自動的に日付も追加して(たまに間違えるとしても)いいんじゃない?DanGさんどうかな?

例えばCやC++は符号付き整数のラップを未定義にしている

ここで言いたかったのは「符号付き整数の『オーバーフロー』を未定義にしている」だと思う。ラップ(回り込み)は確定した挙動だし、オーバーフローは未定義な状況であって、選択すべき結果じゃないからね。

後の方で「Rustのこれら3つの式もLLVMのせいで無効な結果を生成する」って主張しているけど、ここはさらに混乱しているよ。

    x / 0
    INT_MIN / -1
    INT_MAX % -1
    INT_MAX - INT_MIN

INT_MAXやINT_MINをi32::MAXやi32::MIN(または好きな符号付き型)だと定義すれば、Rustで実際に起きるのは単なるパニックだよ。コンパイル時に評価される文脈で書けばコンパイルエラーになる。俺の理解では、それは「無効」というのとはちょっと違う。

Odinについても言及されているけど、詳しくないなりに思うのは、Odinもこんな無茶な処理は拒否するはず。Godboltで見ると、SIGILL(ゼロ除算)かSIGFPE(他の不可能な操作)になるみたいだし。

編集:コピペを間違えたかな?ブログに書かれていた内容と違うものもあったけど、修正しておいた。もちろん、これらはRustでは「無効」ではなく、ゼロ除算のように無意味だからパニックするものもあれば、問題なく動くものもある。どちらにせよ大した問題じゃないよ。

5dataflown約11時間前

ストラウストラップはintよりunsignedを推奨してるし、ダイクストラもGoogleのコーディングガイドラインもintよりunsignedを推奨してる。

ブロガーはunsignedよりintを推奨してる。

どっちを信じるか悩ましいね。

6cpeterso約10時間前

Goのデフォルトのint型を任意の精度のbig intに変更しようという提案があったんだ。オーバーフローのバグは防げるけど、シリアライズされたデータの読み込み時の互換性とパフォーマンスの問題で、8年後に却下されたよ。

https://github.com/golang/go/issues/19623

7bogdanoff_2約10時間前

while(i--)を使えば0までカウントダウンできるよ。

8pikuseru約9時間前

2Dゲームを作っていて左に移動させたいときはどうすればいいの?