unsigned int と int は加算と減算で同じ命令を共有していることに気付きました。ただし、整数除算には idivl / imull を提供し、 unsigned int には乗算、 divl / mull を提供します。この根本的な理由を知ることができますか?
3 に答える
引数が符号付きか符号なしかによって、乗算または除算の結果は異なります。
これは、符号付きと符号なしの加算と減算に同じ演算を使用できるようにする2の補数の魔法です。これは他の表現には当てはまりません。1の補数と符号の大きさはどちらも、符号なし算術とは異なる加算および減算アルゴリズムを使用します。
たとえば、32ビットワードの場合、-1
はで表され0xffffffff
ます。これを2乗すると、符号付きバージョンと符号なしバージョンで異なる結果が得られます。
Signed: -1 * -1 = 1 = 0x00000000 00000001
Unsigned: 0xffffffff * 0xffffffff = 0xfffffffe 00000001
結果の下位ワードは同じであることに注意してください。上位ビットを提供しないプロセッサでは、必要な乗算命令は1つだけです。PPCには、オペランドが符号付きか符号なしかに応じて、下位ビット用と上位ビット用の3つの乗算命令があります。
x86では、符号を上位ビットに格納します(整数と符号なし整数について説明する場合)。ADDコマンドとSUBコマンドは、符号付きと符号なしの両方に1つのアルゴリズムを使用します。両方で正しい結果が得られます。
MULLおよびDIVの場合、これは機能しません。そして、符号付きまたは符号なしで「使用」したいintをCPUに「伝える」必要があります。符号なしの場合は、MULLとDIVを使用します。それは言葉を操作するだけです-それは速いです。署名付きの場合は、MULLとIDIVを使用します。ワードを絶対(正)の値にし、結果の符号を格納してから操作を行います。これはMULLやDIVよりも遅いです。
ほとんどのマイクロプロセッサは、シフトアンドアッド アルゴリズム
(または同様のアルゴリズム) を使用して
乗算と除算を実装します。これにはもちろん、オペランドの符号を個別に処理する必要があります。符号については、符号付き整数値と符号なし整数値を交換可能に処理できるため、効率の低いアルゴリズムであり、使用されなかった可能性があります。
最近の一部の CPU では代わりにBooth エンコード方式が使用されていることを読みましたが、そのアルゴリズムは値の符号をアサートすることも意味しています。