谁有超长整数运算的好算法?
现在CPU还是64位的,量长整数不过int64(2^64),超过这个数的整数怎么办,如1000!等,请各位有心人指点迷津。
[em08][em08][em08]高精度,用一个线性表保存一个大整数,具体说,将大整数写成p进制数,线性表的每一项存p进制其中一位。
参考下面代码
#include <iostream>) d' p, i6 z! a5 K( ~. `/ m #include <memory> # include <string>& n0 N* B. @8 h: c$ h using namespace std;
typedef long long hugeint;
const int Base = 1000000000;% G& S/ _$ Q/ O! H$ l8 t const int Capacity = 200;
struct xnum {0 x6 X1 t5 B- X int Len;1 q; a# b: M% X( H# ~+ x int Data[Capacity];: y0 \0 k' O! i' b6 c% j% z7 r4 ? xnum() : Len(0) {} xnum(const xnum& V) : Len(V.Len) { memcpy(Data, V.Data, Len * sizeof *Data); }* I7 G! A( z- I6 S: ^$ O, r' [ xnum(int V) : Len(0) { for (; V > 0; V /= Base) Data[Len++] = V % Base; } xnum& operator=(const xnum& V) { Len = V.Len; memcpy(Data, V.Data, Len * sizeof *Data); return *this; } int& operator[](int Index) { return Data[Index]; } int operator[](int Index) const { return Data[Index]; }4 A" B( b0 ]9 |) |4 r };
# n3 L9 }8 o1 o' `2 S* @; ^ int compare(const xnum& A, const xnum& B) {; M8 w2 i. C1 c; X8 w! y int I; if (A.Len != B.Len) return A.Len > B.Len ? 1 : -1;4 s$ r0 i' }4 g) R for (I = A.Len - 1; I >= 0 && A[I] == B[I]; I--);6 T2 e. X* u2 ~. {6 d0 `3 C# e if (I < 0) return 0; return A[I] > B[I] ? 1 : -1; }
xnum operator+(const xnum& A, const xnum& B); r( o$ |! M6 }7 J* s" \ {6 L( N, Q' K( N7 } a xnum R; int I; int Carry = 0; for (I = 0; I < A.Len || I < B.Len || Carry > 0; I++)2 F0 n7 z3 ^5 V$ V9 A5 E% C1 c3 t { if (I < A.Len) Carry += A[I]; if (I < B.Len) Carry += B[I];. e3 n7 c! P/ |! d R[I] = Carry % Base; Carry /= Base;; j" G3 Z) `- V1 A7 {: R4 { } R.Len = I; return R; }
xnum operator-(const xnum& A, const xnum& B) E# D5 F# h. S1 q: R8 G {& F2 Q8 J. Q7 O/ W0 {2 d% F xnum R; int Carry = 0; R.Len = A.Len; int I; for (I = 0; I < R.Len; I++)2 T P4 O+ k0 S4 D2 t; Y { R[I] = A[I] - Carry; if (I < B.Len) R[I] -= B[I];* e9 w3 W. p: P! H; `! C if (R[I] < 0) Carry = 1, R[I] += Base;* U* t, x; E! W% m+ b else Carry = 0;9 I& N. z- m3 ^ } while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;* l2 y) E+ H* j; X; C; _3 |+ a return R; }
xnum operator*(const xnum& A, const int B) {. ~2 @& e+ d, c3 ^0 v int I; if (B == 0) return 0;* J1 S \: p" X# V7 i# X& | xnum R;9 r- q0 ]9 @& ?! W" d6 U- h; J hugeint Carry = 0; for (I = 0; I < A.Len || Carry > 0; I++) {+ d" Z" R: R5 U, [: q. U6 E$ L if (I < A.Len) Carry += hugeint(A[I]) * B; R[I] = Carry % Base; Carry /= Base; } R.Len = I;- p" c* M6 A% e1 l, }2 W6 Z# L return R;4 j2 f$ l) a5 k* c- d }
xnum operator*(const xnum& A, const xnum& B)$ W9 v( X6 d$ T/ J) t0 k { int I;( `9 w' a" z6 j7 P: G6 ` if (B.Len == 0) return 0; xnum R; for (I = 0; I < A.Len; I++)9 I6 \0 r: ` m* s- c0 D ?: e' Y# Z/ \ { hugeint Carry = 0; for (int J = 0; J < B.Len || Carry > 0; J++) {& P2 p+ a% M# s2 p/ {$ @- c if (J < B.Len) Carry += hugeint(A[I]) * B[J]; if (I + J < R.Len) Carry += R[I + J];2 f1 y& }( L3 I7 l0 U6 o if (I + J >= R.Len) R[R.Len++] = Carry % Base;6 S0 N4 u, u8 `# {1 n3 q else R[I + J] = Carry % Base;/ A6 L! b8 c, o5 H7 \ Carry /= Base; } }" P7 G3 [# t6 i' b+ s% z return R;3 Q- e+ l5 E8 l8 k' k }
xnum operator/(const xnum& A, const int B) { xnum R;1 X B+ a+ D: f \+ V/ C; G. m2 O+ D int I; hugeint C = 0; for (I = A.Len - 1; I >= 0; I--)5 W+ c1 M: Q% `9 |# l) [ { C = C * Base + A[I]; R[I] = C / B; C %= B;! U& a; H$ D c }4 G; G5 P+ A; g1 d; `4 [ R.Len = A.Len;# c$ U' S6 [: R* D while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--; return R; }
xnum operator/(const xnum& A, const xnum& B)" U" o8 x8 B7 S {- W- D9 {. s: w: H9 g% l7 Z int I;3 [2 Q6 z N. ~ xnum R, Carry = 0;" `' [" P+ S- q6 V int Left, Right, Mid;" |- ^! T+ s; V3 U. O% m7 g/ W- l for (I = A.Len - 1; I >= 0; I--); B1 h+ b; n, @3 ~. I o* k3 k {0 ^2 }, y, V1 C6 j: c Carry = Carry * Base + A[I];/ _7 n* E3 Q. X+ i: e. Z Left = 0; Right = Base - 1;& Z$ j& y( z& `+ _: i while (Left < Right) { Mid = (Left + Right + 1) / 2;9 X4 F' A. k* _# p0 B2 y+ } if (compare(B * Mid, Carry) <= 0) Left = Mid; else Right = Mid - 1;/ i0 Y# G3 F% ~3 B3 m- a/ Y: i } R[I] = Left;& d( y: R" R/ n' k6 i: @ Carry = Carry - B * Left;1 r7 K- W+ \% |+ d } R.Len = A.Len;. }- A+ @0 t; p- D while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--; return R;. E7 Z) c4 {$ \! J: U1 |6 L' s } xnum operator%(const xnum& A, const xnum& B)9 U% q9 w( O# z) Y6 O% A( ^ { int I;; N( S# d- I, _9 J6 S. F xnum R, Carry = 0;6 u7 ~) t& T3 y0 | E4 Q% b int Left, Right, Mid; for (I = A.Len - 1; I >= 0; I--)% O4 k) E7 E) m" d: Y4 a { Carry = Carry * Base + A[I]; Left = 0;$ M" I; q3 |( W: l0 O9 ^; \' ]% r: u4 t Right = Base - 1;( O2 q) {% z" i1 B4 Y: d6 D! R while (Left < Right) { Mid = (Left + Right + 1) / 2; if (compare(B * Mid, Carry) <= 0) Left = Mid; else Right = Mid - 1; }: j7 C0 |0 M1 c5 u R[I] = Left;" T) E6 K/ m4 a" }# _ Carry = Carry - B * Left; } R.Len = A.Len;* `. ` H# d' z& x$ V/ F9 Z: A) } while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;6 C( Q7 X, P& |: X2 S6 R# w& Y return Carry;8 G- ?% c# C+ B' ?7 @ }
istream& operator>>(istream& In, xnum& V) {" i" x# Z9 y% x" i char Ch;9 @: j4 o/ C+ _6 x for (V = 0; In >> Ch;)3 @1 {- n4 T, V/ J {1 [, w% L' j4 \# O& F V = V * 10 + (Ch - '0');; b: O' u/ ^0 O( m if (cin.peek() <= ' ') break;, R1 Z6 C2 b% P5 Z9 ~$ q } return In; }
ostream& operator<<(ostream& Out, const xnum& V)! M" m7 q" J1 h3 t" h. |1 V. b {/ Y- v( X" O1 m4 L+ C& e int I;" N: z( J8 T2 w& Z) C' z8 e Out << (V.Len == 0 ? 0 : V[V.Len - 1]); for (I = V.Len - 2; I >= 0; I--) for (int J = Base / 10; J > 0; J /= 10) Out << V[I] / J % 10; return Out;- b; `( V* I4 B, S }
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |