C/C++高精度(加減乗除)アルゴリズムバイナリ最適化

高度な高精度アルゴリズムシリーズ

第 1 章 簡単な実装
第 2 章 圧縮の最適化
第 3 章 バイナリの最適化 (本章)



序文

前章「C/C++高精度(加減乗除)アルゴリズム圧力ビット最適化」で、最適化された高精度計算を実現しました。 int32を使用した整数配列の各要素は、10進数9個を格納できます。さらに最適化したい計算速度により、データの保存方法を変更し、2 進数の保存数値を使用できます。int32 配列は、数値をバイナリで格納するために今でも使用されており、計算効率が高いだけでなく、最高のスペース使用率も実現します。


1. 基本原則

1. 保管方法

ストレージのバイナリ順序は低位から高位の順に格納されます
ここに画像の説明を挿入

2. 計算方法

計算方法は10進数記憶の計算方法と基本的に同じで、int8の計算方法は以下の通り、int16、int32なども基本的に同じです。
ここに画像の説明を挿入


2. 重要な実現

1. 整数から高精度配列(バイナリ)へ

これはビット演算によって実現できます (例として要素型 int32)。

/// <summary>
/// 通过无符号整型初始化
/// </summary>
/// <param name="a">[in]高精度数组</param>
/// <param name="value">[in]整型值</param>
static void loadInt(int* a, uint64_t value) {
    
    
	a[1] = (uint32_t)value;
	a[2] = value >> (sizeof(int) * 8);
	a[0] = a[2] ? 2 : 1;
}

2.文字列を高精度配列(バイナリ)に変換

ここでは、まず高精度な加算と乗算を実現する必要がある方法を提供します。
(1) 高精度配列の値を 0 に初期化します
(2) 文字列内の数値を 1 つずつ取得します
(3) 高精度配列を 10 倍します
(4) 取得した数値を高精度配列に加算します (整数から高精度配列へは上記参照 セクション)
(5) 文字列が読み込まれていないため、(2)に戻ります。

3.高精度配列(バイナリ)を文字列に変換する

ここでは、前章の実装を補助的に必要とするメソッド「C/C++ 高精度 (加減乗除) アルゴリズム圧縮の最適化」
(1) 9 ビットの高プログレス配列の値を 0 に初期化します。
(2) 1 つずつ高精度を取得します。 配列の要素 (バイナリ)
(3) 9 ビットの高進行配列を掛けると 2^32 になります (バイナリ配列の要素型 int32 は例です)
(4) 取得した要素が 9 ビットのハイプログレス配列に追加されます
(5) 要素は未読です (2) に戻った後
(6) 9 桁のハイプログレス配列を押して文字列を変換します


3. 完全なコード

インターフェイスと使用方法は第 1 章「C/C++ 高精度 (加算、減算、乗算、除算) アルゴリズムの簡単な実装」とまったく同じであるため、ここでは完全なコードのみを提供します。使用例については第 1 章を参照してください
int32配列バイナリ ストレージに基づく高精度アルゴリズム:
https://download.csdn.net/download/u013113678/87720242


4. 性能比較

テストプラットフォーム: Windows 11
テスト機器: i7 8750h
テスト方法: 5 回のテストの平均値を取る
表 1、テストケース

テストケース 説明
1 整数範囲デジタル演算50万回
2 長い数値と整数範囲の数値は 500,000 回計算されます
3 長い数値と 500,000 回計算された長い数値

上記のユースケースに基づいてプログラムを作成してテストします。テスト結果を次の表に示します。 表
2、テスト結果

計算する テストケース 9 ビットの最適化 (前の章) の圧縮には時間がかかる バイナリ最適化 int32 (この章) 時間がかかる
添加 テストケース1 0.002620秒 0.0024862秒
添加 テストケース2 0.005711秒 0.0034712秒
添加 テストケース 3 0.005384秒 0.003857秒
蓄積する テストケース1 0.002536秒 0.0027246秒
蓄積する テストケース2 0.002592秒 0.0029876秒
蓄積する テストケース 3 0.006474秒 0.0043758秒
引き算 テストケース1 0.002078秒 0.0022704秒
引き算 テストケース2 0.004939秒 0.0032914秒
引き算 テストケース 3 0.004929秒 0.0041246秒
累積的 テストケース1 0.002034秒 0.0020808秒
累積的 テストケース2 0.001942秒 0.0023542秒
累積的 テストケース 3 0.004282秒 0.0044144秒
乗算 テストケース1 0.004751秒 0.0038996秒
乗算 テストケース2 0.028358秒 0.0117986秒
乗算 テストケース 3 0.064259秒 0.0185958秒
乗算 テストケース 1 は 1000 回のみ計算します 0.000137秒 0.000062秒
乗算 テストケース 2 は 1000 回のみ計算します 0.000187秒 0.0000816秒
乗算 テストケース 3 は 1000 回のみ計算します 0.081988秒 0.0292832秒
分割 テストケース1 0.024763秒 0.0196498秒
分割 テストケース2 0.516090秒 0.3556564秒
分割 テストケース 3 0.073812秒 0.1716874秒
累積除算 テストケース 1 は 1000 回のみ計算します 0.035722秒 0.0009416秒
累積除算 テストケース 2 は 1000 回のみ計算します 0.060936秒 0.0131722秒
累積除算 テストケース 3 は 500 回のみ計算します 25.126072秒 2.6210544秒

上表のデータを同じ種類に分類し、平均値を取ると下図のように改善速度が計算されます(参考値です)。

図1. 速度の向上

ここに画像の説明を挿入


要約する

以上が今日お話したい内容ですが、バイナリストレージ最適化は9ビット最適化に比べて速度が向上しており、格納方法も整数と同じなのでスペースを有効活用できます。圧縮された 9 ビット アルゴリズムと比較して、バイナリ アルゴリズムでは乗算と除算が大幅に改善され、特に長いデータ演算の改善がより顕著です。この章でのアルゴリズムのバイナリ変換方法の実装は c# の BigInt を参照していますが、一般に、このアルゴリズムは高精度でパフォーマンスが優れており、プロジェクト開発に適しています。


おすすめ

転載: blog.csdn.net/u013113678/article/details/130320216