std.bigint
多倍長整数演算のための BigInt 構造体を提供します。内部表現は、10進ではなく2進表現となっています。
整数演算に関する全ての演算子がオーバーロードされています。
Example:
BigInt a = "9588669891916142"; BigInt b = "7452469135154800"; auto c = a * b; assert(c == "71459266416693160362545788781600"); auto d = b * a; assert(d == "71459266416693160362545788781600"); assert(d == c); d = c * "794628672112"; assert(d == "56783581982794522489042432639320434378739200"); auto e = c + d; assert(e == "56783581982865981755459125799682980167520800"); auto f = d + c; assert(f == e); auto g = f - c; assert(g == d); g = f - d; assert(g == c); e = 12345678; g = c + e; auto h = g / b; auto i = g % b; assert(h == a); assert(i == e);
Authors:
Janice Caron
Date:
2008.05.18
License:
Public Domain
- uint の alias
- 多倍長整数を表す構造体
- 多倍長の加算
dest[] = src1[] + src2[] + carry (0 or 1)
または減算 dest[] = src1[] - src2[] - carry (0 or 1)。
繰り上がりまたは繰り下がり (0 or 1) を返します。
加算には op == '+'、減算には '-' をセットします。
X86 プロセッサでは、任意精度算術 ('bignum')
に最適化されたアセンブラルーチンが使用されます。
全ての関数は、LSB first で格納された uint の配列に対する処理となっています。 出力先配列のある関数では、それは常に戦闘の引数です。 現在のところ、これらの関数は全て変更の可能性があり、 内部での使用のみを意図しています。
Author:
Don Clugston
Date:
May 2008.
License:
Public Domain
おおまかに言って、モダンな x86 マイクロアーキテクチャには3種類あります: (a) Intel の P6 ファミリ (Pentium Pro, PII, PIII, PM, Core); (b) AMD の K6, Athlon, AMD64 ファミリ; (c) Pentium 4
このコードは、使う命令セットを基本的なものに限っている(MMX, SSE, SSE2 を使っていない) ことを除けば、Intel P6 ファミリに最適化されています。 どのCPUも基本的には同じパイプラインを使うため、 EAX-> RAX 等の変換後のコードも、Core2 に対してもほぼ最適となっています。 このコードでは、www.agner.org で公開されている Agner Fog の superb manual で解説されたテクニックを使用しています。 1サイクルで2つのメモリロードが可能(Intelは1つ)な AMD64 に対する最適なコードとはなっていません。
Timing results (cycles per int) PentiumM Core2 +,- 2.25 2.25 &,|,^ 2.0 2.0 <<,>> 2.0 2.0 cmp 2.0 2.0 * 5.0 mulAdd 5.4 div 18.0 - op には '+' または '-' を指定し、 それぞれ dest[] += carry か dest[] -= carry を計算します。 最後の繰り上がりまたは繰り下がり (0 or 1) を返します。
- op == '&' または '|' または '^' に対して、Dest[] = src1[] op src2[]
