4

数値が別の数値で割り切れるかどうかを C で確認する最良の方法はどれですか? 私はこれを使用します:

if (!(a % x)) {
// this will be executed if a is divisible by x
}

とにかく速いのはありますか?つまり、130 % 13 を実行すると、10 回あたり 130 / 13 を実行することになります。したがって、1 つだけが必要な場合は 10 サイクルあります (130 が 13 で割り切れるかどうかを知りたいだけです)。

ありがとう!

4

5 に答える 5

28

つまり、130 % 13 を実行すると、10 回あたり 130 / 13 を実行することになります。

たわごと。%私が今まで使用したどのプロセッサでもそのようなことはしません。1 回実行し130/13、残りを返します。

を使用し%ます。アプリケーションの実行が遅すぎる場合は、プロファイリングして遅すぎる部分を修正します。

于 2011-05-25T19:35:19.137 に答える
8

任意の 2 つの数値について、確認する最善の方法は、 かどうかを確認することa % b == 0です。モジュラス演算子は、ハードウェアによってパフォーマンスが異なりますが、コンパイラの方がはるかに優れています。モジュラス演算子は普遍的であり、コンパイラは、実行しているハードウェアに関係なく、出力する命令の最適なシーケンスを見つけ出します。

数値の 1 つが定数の場合、ハードウェアの div/mod は加算や減算よりも遅いため、コンパイラはビット シフトと減算の組み合わせ (ほとんどは 2 の累乗) を実行して最適化する可能性がありますが、最新のプロセッサではレイテンシ (既にわずか数ナノ秒) は、他の多くのパフォーマンス トリックによって隠されているため、心配する必要はありません。除算を繰り返してモジュラスを計算するハードウェアはありません (一部の古いプロセッサは、ビット シフトと減算を繰り返して除算を行いましたが、それでも専用のハードウェアを使用していたため、ソフトウェアでエミュレートするよりもハードウェアで実行する方が高速です)。最近のほとんどの ISA は、実際には除算と剰余の両方を 1 つの命令で計算します。

有効な唯一の最適化は、除数が 2 のべき乗である場合です。次に&、下位ビットを (除数 - 1 で) マスクし、結果をゼロに対してチェックするために使用できます。たとえば、がa8 で割り切れるかどうかを確認することa & 7 == 0は同等です。優れたコンパイラがこれを行うので、そのままにしておいてください%

于 2011-05-25T19:49:48.367 に答える
6

一般的なケースでは、剰余演算子を使用するのが最も高速な方法である可能性があります。特に数値が 2 の累乗で割り切れるかどうかに関心がある場合 (この場合、ビット単位の演算が利用可能) には例外がありますが、単に を使用する場合、コンパイラはそれらを自動的に選択する必要があります%。などの任意の値に対しては、これ以上うまくいく可能性はほとんどありません13

また、「10回あたり130/13を行う」とはどういう意味ですか?それは130 / 13一度です。これはまさに必要なものです。

于 2011-05-25T19:36:07.407 に答える
3

xが定数の場合、はい:

if (a * 0x4ec4ec4ec4ec4ec5 < 0x13b13b13b13b13b2) {
    // this will be executed if a is divisible by 13
}

0x4ec4ec4ec4ec4ec5は 13 の剰余乗法逆数(剰余 2 64 ) であるため、aが実際に 13 の倍数である場合、積は (2 64 /13) より小さくなります。( a は整数nの 13 倍であり、2 64n未満であることを意味する 64 ビット ワードに収まる必要があるためです。)

これは の奇数値に対してのみ機能しますx。偶数 (つまり、y>0 の 2 yの倍数) の場合、このテストをビットごとの AND テストと組み合わせることができます (の最後のyビットはaゼロである必要があります。それらがa2 yで除算され、乗算テストに進む場合)。

x乗法逆数の計算は整数除算よりもコストがかかるため、これは が定数の場合にのみ価値があります。


編集:私も想定してaおりx、署名されていません。

于 2011-05-25T19:57:11.017 に答える
0

機械は%除算命令を実行するだけで、剰余が自動的に生成されます。

ただし、数値の 1 つが負の場合、%は負の余りを与えることに注意してください。0 の剰余のみを気にする場合、これは問題ではありませんが、1 などの別の剰余を探している場合は、本当につまずく可能性があります。

于 2011-05-25T23:02:22.857 に答える