谁有超长整数运算的好算法?
Z4 A' K. }$ r( p+ Q现在CPU还是64位的,量长整数不过int64(2^64),超过这个数的整数怎么办,如1000!等,请各位有心人指点迷津。
[em08][em08][em08]高精度,用一个线性表保存一个大整数,具体说,将大整数写成p进制数,线性表的每一项存p进制其中一位。
参考下面代码
#include <iostream> #include <memory>: J0 S" N( L! \9 H- b" s4 x # include <string>$ l( N# m" ~* y; A, \% s' p1 b) V using namespace std;
typedef long long hugeint;
const int Base = 1000000000; const int Capacity = 200;
struct xnum+ v& P' b m2 R; T7 y$ ]6 w {4 F( I( i4 ?- J) z& ~7 f int Len; int Data[Capacity]; xnum() : Len(0) {}9 |/ L7 ^; z$ m5 I) N# r e4 m xnum(const xnum& V) : Len(V.Len) { memcpy(Data, V.Data, Len * sizeof *Data); } xnum(int V) : Len(0) { for (; V > 0; V /= Base) Data[Len++] = V % Base; }- v- ^5 u- D; k6 N, \8 `# S; F+ ?) S7 g xnum& operator=(const xnum& V) { Len = V.Len; memcpy(Data, V.Data, Len * sizeof *Data); return *this; } int& operator[](int Index) { return Data[Index]; }0 t* q4 F2 k6 Y/ z5 L; i. O int operator[](int Index) const { return Data[Index]; } };
: _) b" M* r& \4 Y int compare(const xnum& A, const xnum& B) {3 K, c( v" P' i6 I+ F" ^ int I; if (A.Len != B.Len) return A.Len > B.Len ? 1 : -1;* h- D3 k9 w R9 k1 L( p for (I = A.Len - 1; I >= 0 && A[I] == B[I]; I--); if (I < 0) return 0; return A[I] > B[I] ? 1 : -1;( p7 \1 L# }! z5 ~. H0 O }
xnum operator+(const xnum& A, const xnum& B) {4 F3 e4 \, r# I xnum R; int I; int Carry = 0; for (I = 0; I < A.Len || I < B.Len || Carry > 0; I++) { if (I < A.Len) Carry += A[I];/ K& m6 y) W- B6 A if (I < B.Len) Carry += B[I]; R[I] = Carry % Base; Carry /= Base;9 c' j8 z* _# `7 x& {( _+ e } R.Len = I;: u( M* `/ w% ^2 b2 l( g) p, M return R; }
xnum operator-(const xnum& A, const xnum& B)! e0 Q z6 o5 t" P8 e s7 d {" N4 a& r7 W% P9 p$ r" o* F2 t xnum R; int Carry = 0; R.Len = A.Len; int I;7 _; U$ \( A) _+ X% _# q2 F for (I = 0; I < R.Len; I++) Z+ u. h" s' O! _+ u {: R% [- j0 U- s" V R[I] = A[I] - Carry; if (I < B.Len) R[I] -= B[I];# S+ Y4 X$ ^) `( ~1 S if (R[I] < 0) Carry = 1, R[I] += Base; else Carry = 0; }7 b A! [: `& g+ T# I: u7 F while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;1 W. ]1 Q& |- J2 m) A return R;* G% {( X+ I$ V1 O' V/ g }
xnum operator*(const xnum& A, const int B)" R6 p+ {1 C" K7 J0 ?0 c, U7 ` { int I; if (B == 0) return 0; xnum R;/ |6 b5 g6 k1 B4 @2 {1 m& c hugeint Carry = 0; for (I = 0; I < A.Len || Carry > 0; I++) {, U4 b5 L7 G9 } if (I < A.Len) Carry += hugeint(A[I]) * B; R[I] = Carry % Base; l3 _' \+ Y8 C! B) }* d% M( _/ h Carry /= Base; } R.Len = I;& _7 L& Z" j$ W# X# \0 { return R;) ~% w% z4 D3 @8 L- } Z }
xnum operator*(const xnum& A, const xnum& B)8 X4 x5 x$ q) N { int I;$ {: y" l4 V3 \5 {+ B if (B.Len == 0) return 0;" Z+ m. y5 k3 J xnum R;! l- R1 I& `$ O6 M for (I = 0; I < A.Len; I++)- b* C3 U2 f% a% j6 [ { hugeint Carry = 0;" i' U* e; j v( v* R% g for (int J = 0; J < B.Len || Carry > 0; J++) {2 F9 c; j4 u; Z3 A# F$ D) { if (J < B.Len) Carry += hugeint(A[I]) * B[J]; if (I + J < R.Len) Carry += R[I + J];8 P+ @5 x6 O& t. p if (I + J >= R.Len) R[R.Len++] = Carry % Base;& g& R# P1 D5 ^; ` J7 l else R[I + J] = Carry % Base; Carry /= Base; } }3 V1 l' q- j$ @6 h, i+ ` return R; }
xnum operator/(const xnum& A, const int B) { xnum R; int I; hugeint C = 0;) N9 p; @* {" C, L for (I = A.Len - 1; I >= 0; I--)( p# C7 n' ~3 k. _1 t/ `5 m { C = C * Base + A[I]; R[I] = C / B;, U# f: x& U2 }' L C %= B; } R.Len = A.Len; while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--; return R; }
xnum operator/(const xnum& A, const xnum& B)6 a% V7 t0 z$ {( i3 U& `$ u/ Y {+ |+ U3 m# g1 m) A& E4 N4 h int I; xnum R, Carry = 0;9 O7 B3 v8 \- G ? int Left, Right, Mid; for (I = A.Len - 1; I >= 0; I--)& b# A! Y# B2 p& r { Carry = Carry * Base + A[I]; Left = 0; Right = Base - 1;$ ?* O- C4 i; Z- \ while (Left < Right)3 b) y7 _2 }- g) O3 L: ]- }4 v { Mid = (Left + Right + 1) / 2;* C7 ]6 N# {2 o8 m, w) `# @ if (compare(B * Mid, Carry) <= 0) Left = Mid; else Right = Mid - 1;* a s0 @6 C# k' o3 x0 h, ?- F7 Q }, x& f6 Y# V/ K4 Z5 ?) a R[I] = Left;6 H ~* ?, ^+ {! ?4 U* K' M Carry = Carry - B * Left; } R.Len = A.Len; while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--; return R;" w* I) i4 @( c0 h# Z: n( `( A } xnum operator%(const xnum& A, const xnum& B) {/ T5 G6 P1 S, V" t: O( @ int I; xnum R, Carry = 0;1 [# t, l4 A# q int Left, Right, Mid;) E, _. i; \) v for (I = A.Len - 1; I >= 0; I--) { Carry = Carry * Base + A[I];2 g0 S( Y q/ s& V7 ~7 h1 | Left = 0; Right = Base - 1; while (Left < Right)' Y) V" t/ ^8 G3 u3 v' _8 e {% }: T) P1 m, h2 y+ L Mid = (Left + Right + 1) / 2; if (compare(B * Mid, Carry) <= 0) Left = Mid; else Right = Mid - 1;& A! F7 r* l; s+ f }- [6 l' G/ }& u R[I] = Left; Carry = Carry - B * Left; } R.Len = A.Len; while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;6 D& S$ G1 Y3 l+ _. _ return Carry;: w1 ]0 E& z9 k+ H; _ }
istream& operator>>(istream& In, xnum& V)5 W" P* N8 N8 e, m, l! x* \ { char Ch; for (V = 0; In >> Ch;)& q$ g4 j: c" B2 p { V = V * 10 + (Ch - '0');1 J# ]) }5 _) s! E d# ^8 N6 _ if (cin.peek() <= ' ') break;/ p& P$ N* g3 T7 R6 S, A) d, ` }- r( i. F8 U$ @) j5 ?7 V4 ? return In;3 ~0 }) G" \, Z% ~ }
ostream& operator<<(ostream& Out, const xnum& V) { int I;: U% O- r; O) V% d, `, n. n Out << (V.Len == 0 ? 0 : V[V.Len - 1]);+ l9 c. O$ I- ~+ D+ [+ S7 I0 _5 t* P for (I = V.Len - 2; I >= 0; I--) for (int J = Base / 10; J > 0; J /= 10) Out << V[I] / J % 10;7 W, _2 {1 w/ L+ s) d6 I$ m5 @ return Out;. g* i0 `; G# ^ }
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |