10

除算を切り上げて示すコード (C 構文):

#define SINT64 long long int
#define SINT32 long int

SINT64 divRound(SINT64 dividend, SINT64 divisor)
{
  SINT32 quotient1 = dividend / divisor;

  SINT32 modResult = dividend % divisor;
  SINT32 multResult = modResult * 2;
  SINT32 quotient2 = multResult / divisor;

  SINT64 result = quotient1 + quotient2;

  return ( result );
}

divdi3()さて、これがユーザー空間である場合、コンパイラがそれらの演算子 (除算など) のコードを生成していることに気付かないでしょう。libgcc知らないうちにリンクしている可能性があります。問題は、カーネル空間が異なることです (例: no libgcc)。何をすべきか?

Google をしばらくクロールすると、ほとんどの人が署名されていないバリアントに対処していることに注意してください。

#define UINT64 long long int
#define UINT32 long int

UINT64 divRound(UINT64 dividend, UINT64 divisor)
{
  UINT32 quotient1 = dividend / divisor;

  UINT32 modResult = dividend % divisor;
  UINT32 multResult = modResult * 2;
  UINT32 quotient2 = multResult / divisor;

  UINT64 result = quotient1 + quotient2;

  return ( result );
}

私はこれを修正する方法を知っています: Override udivdi3()and umoddi3()with do_div()from asm/div64.h。できましたか?違う。Signed は unsigned と同じではsdivdi3()なく、単純に を呼び出すudivdi3()のではなく、理由により別の関数です。

この問題は解決しましたか?これを行うのに役立つライブラリを知っていますか? 私は本当に立ち往生しているので、ここに表示されているものは何でも、私が今は本当に役に立たないでしょう.

ありがとう、チャド

4

4 に答える 4

5

この機能は、カーネル v2.6.22 の時点で/linux/lib/div64.cに導入されています。

于 2008-10-12T21:52:44.870 に答える
4

これが私の本当に素朴な解決策です。あなたのマイレージは異なる場合があります。

である符号ビットを保持しsign(dividend) ^ sign(divisor)ます。(または*、または/、false と true ではなく、符号を 1 と -1 として格納する場合。基本的に、どちらか一方が負の場合は負、どちらも負でない場合は正です。)

次に、両方の絶対値に対して符号なし除算関数を呼び出します。次に、サインを結果に戻します。

PSそれは実際に__divdi3実装されている方法ですlibgcc2.c(私のUbuntuシステムにインストールされているバージョンであるGCC 4.2.3から)。私はちょうどチェックしました。:-)

于 2008-08-29T23:45:58.797 に答える
0

ldiv?

編集:タイトルを読み直してください。これは無視してください。適切な非ライブラリ バージョンがあるかどうかによって異なります。

于 2008-08-29T23:31:28.533 に答える
0

do_div()は実際に被除数をその場で変更するため、この場合、クリスの答えが機能するとは思わない (少なくとも作成する方法を見つけることはできません) 。絶対値を取得するということは、必要な方法で値が変更される一時変数を意味しますが、__divdi3()オーバーライドから渡すことはできません。

この時点では、 do_div()で使用される手法を模倣することを除いて、 __divdi3 ()の値によるパラメーター署名を回避する方法はわかりません。

ここで後ろ向きに曲がっているように見えるかもしれませんが、実際に必要な 64 ビット/32 ビット除算を行うアルゴリズムを考え出す必要があります。ただし、ここでさらに複雑になるのは、「/」演算子を使用した数値コードがたくさんあり、そのコードを調べて、すべての「/」を関数呼び出しに置き換える必要があることです。

私はそれをするのに十分必死になっています。

フォローアップありがとう、チャド

于 2008-09-02T16:06:26.620 に答える