128ビットの数値を2つの64ビットの数値(「Hi」と「Lo」)として格納しています。32ビットの数値で割るだけです。CPUからのネイティブ64ビット演算を使用して、どうすればそれを行うことができますか?
(任意精度のライブラリは必要ないことに注意してください。ネイティブ操作を使用してこの単純な除算を行う方法を知っておく必要があります。ありがとうございます)。
128ビットの数値を2つの64ビットの数値(「Hi」と「Lo」)として格納しています。32ビットの数値で割るだけです。CPUからのネイティブ64ビット演算を使用して、どうすればそれを行うことができますか?
(任意精度のライブラリは必要ないことに注意してください。ネイティブ操作を使用してこの単純な除算を行う方法を知っておく必要があります。ありがとうございます)。
アーキテクチャが処理できる最大のネイティブ表現(64ビット)を使用して値(128ビット)を格納している場合、除算の中間結果を処理する際に問題が発生します(すでに見つけたように:))。
ただし、いつでも小さい表現を使用できます。32ビットの4つの数はどうですか?このようにして、オーバーフローの問題なしにネイティブの64ビット操作を使用できます。
簡単な実装(Delphiで)はここにあります。
CPUからのネイティブ64ビット演算を使用して、どうすればそれを行うことができますか?
ネイティブ操作が必要なため、いくつかの組み込み型または組み込み関数を使用する必要があります。上記のすべての答えは、分割命令にコンパイルされない一般的なCソリューションのみを提供します
最新の64ビットコンパイラのほとんどには、128x64の除算を行う方法がいくつかあります。MSVCを使用する場合は、電話する必要が_div128()
あり_udiv128()
ます_udiv128(hi, lo, divisor, &remainder)
_div128
組み込み関数は、128ビット整数を64ビット整数で除算します。戻り値は商を保持し、組み込み関数はポインターパラメーターを介して剰余を返します。_div128
Microsoft固有です。
Clang、GCC、ICCには__int128
タイプがあり、それを直接使用できます
unsigned __int128 div128by32(unsigned __int128 x, uint64_t y)
{
return x/y;
}
Lo32 DECIMAL
、Mid32、Hi32=96ビットの3つの32ビット値で構成される構造があります。
私のCコードは、128ビット、256ビット、512ビット、さらには1024ビットの除算に簡単に拡張できます。
// in-place divide Dividend / Divisor including previous rest and returning new rest
static void Divide32(DWORD* pu32_Dividend, DWORD u32_Divisor, DWORD* pu32_Rest)
{
ULONGLONG u64_Dividend = *pu32_Rest;
u64_Dividend <<= 32;
u64_Dividend |= *pu32_Dividend;
*pu32_Dividend = (DWORD)(u64_Dividend / u32_Divisor);
*pu32_Rest = (DWORD)(u64_Dividend % u32_Divisor);
}
// in-place divide 96 bit DECIMAL structure
static bool DivideByDword(DECIMAL* pk_Decimal, DWORD u32_Divisor)
{
if (u32_Divisor == 0)
return false;
if (u32_Divisor > 1)
{
DWORD u32_Rest = 0;
Divide32(&pk_Decimal->Hi32, u32_Divisor, &u32_Rest); // Hi FIRST!
Divide32(&pk_Decimal->Mid32, u32_Divisor, &u32_Rest);
Divide32(&pk_Decimal->Lo32, u32_Divisor, &u32_Rest);
}
return true;
}