31

場合によっては、一般に、無限を表すのに十分な大きさの整数値を使用します。私は通常、表現可能な最大の正/負の整数を使用します。オーバーフローを避けるために、事実上すべての算術演算の前にオペランドの 1 つが無限大かどうかをチェックする必要があるため、通常はより多くのコードが生成されます。場合によっては、飽和整数演算が望ましい場合があります。そのため、オーバーフローせずに数回加算または乗算できる無限大に小さい値を使用する人もいます。私が興味をそそられるのは、(特にプログラミングコンテストで)非常に一般的に見られるという事実です。

const int INF = 0x3f3f3f3f;

なぜその数は特別なのですか?バイナリ表現は次のとおりです。

00111111001111110011111100111111

ここには特に興味深いプロパティはありません。入力するのは簡単ですが、それが理由であれば、ほとんど何でも構いません (0x3e3e3e3e、0x2f2f2f2f など)。オーバーフローすることなく 1 回追加できるため、次のことが可能になります。

a = min(INF, b + c);

しかし、その場合、他のすべての定数で十分です。グーグルは、その定数を使用する多くのコードスニペットのみを表示しますが、説明やコメントは表示しません。

誰でもそれを見つけることができますか?

4

3 に答える 3

32

ここでこれに関するいくつかの証拠を見つけました(中国語の元のコンテンツ)。基本的な考え方は、0x7ffffffff は既に 4 バイトの符号付き int の範囲の「トップ」であるため、問題があるということです。したがって、それに何かを追加すると、負の数になります。0x3f3f3f3f、代わりに:

  • まだかなり大きい (0x7fffffff と同じ桁数)。
  • 多くのヘッドルームがあります。整数の有効な範囲がそれ以下の数値に制限されていると言う場合、それに「有効な正の数値」を追加しても、無限 (つまり、何か>=INF) を取得できます。オーバーフローもINF+INFしません。これにより、常に「制御下」に保つことができます。

    a+=b;
    if(a>INF)
        a=INF;
    
  • 等しいバイトの繰り返しです。つまり、簡単にmemset詰め込むことができINFます。

  • また、@Jörg W Mittagが上で気づいたように、メモリダンプを見てその場でそれを見つけ、メモリに直接書き込むことができる素晴らしいASCII表現を持っています。
于 2013-08-25T12:58:57.217 に答える
10

0x3f3f3f3f文字列の ASCII 表現です????

Krugle は、データベース全体でその定数の 48 のインスタンスを見つけました。これらのインスタンスのうち 46 は Java プロジェクトにあり、グラフィック操作のビットマスクとして使用されます。

1 プロジェクトはオペレーティング システムであり、未知の ACPI デバイスを表すために使用されます。

1 プロジェクトは、Java グラフィックスのビットマスクです。

そのため、Krugle によって索引付けされたすべてのプロジェクトで、ビットパターンのために 47 回使用され、ASCII 解釈のために 1 回使用され、無限の表現として 1 回も使用されませんでした。

于 2013-08-25T12:53:00.640 に答える