谁有超长整数运算的好算法?
现在CPU还是64位的,量长整数不过int64(2^64),超过这个数的整数怎么办,如1000!等,请各位有心人指点迷津。
[em08][em08][em08]高精度,用一个线性表保存一个大整数,具体说,将大整数写成p进制数,线性表的每一项存p进制其中一位。
参考下面代码
#include <iostream>1 \; k% |1 [, E# D# J8 J #include <memory>1 e& Y" u; w5 ^' [% ]9 i; E8 X # include <string> using namespace std;
typedef long long hugeint;
const int Base = 1000000000;1 ]2 f4 n2 C' F& }% C- y; a+ _ const int Capacity = 200;
struct xnum { int Len; int Data[Capacity];. w6 S7 Z: P" n xnum() : Len(0) {} 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; } xnum& operator=(const xnum& V) { Len = V.Len; memcpy(Data, V.Data, Len * sizeof *Data); return *this; } int& operator[](int Index) { return Data[Index]; }" r: |3 T3 o1 H- G; u! S int operator[](int Index) const { return Data[Index]; }( `' n: W5 A2 R* I! z };
; D7 j* J; b3 [( Z int compare(const xnum& A, const xnum& B) {6 V, \! a4 t. Y9 m9 _& }7 v( q$ T" m2 x int I; if (A.Len != B.Len) return A.Len > B.Len ? 1 : -1;4 C" n: y4 r9 _- I% V; x for (I = A.Len - 1; I >= 0 && A[I] == B[I]; I--);$ P. M9 L- H# W4 J9 L if (I < 0) return 0; return A[I] > B[I] ? 1 : -1; }
xnum operator+(const xnum& A, const xnum& B)# x7 m+ s9 M9 w0 E- E { xnum R; int I; int Carry = 0;# J, |& t$ c4 P9 N, s0 b: n; u& x for (I = 0; I < A.Len || I < B.Len || Carry > 0; I++) { if (I < A.Len) Carry += A[I];6 l) S2 J: O. z# d: ?7 e if (I < B.Len) Carry += B[I]; R[I] = Carry % Base;4 O E' c. k. J Carry /= Base;$ \, y$ R- n1 z; Y' a } R.Len = I;" ~: G2 I* e" | k' S% L return R;* H# R* z3 u+ D8 m5 ~' w }
xnum operator-(const xnum& A, const xnum& B) { xnum R; int Carry = 0; R.Len = A.Len;2 |" T" c N+ Q2 O$ f0 J int I; for (I = 0; I < R.Len; I++)- Y1 k+ D2 D- a) }' O4 h5 o { R[I] = A[I] - Carry;7 J, ?7 H+ \! d' R0 f6 g6 \ if (I < B.Len) R[I] -= B[I];3 S3 T' ^# H# l if (R[I] < 0) Carry = 1, R[I] += Base; else Carry = 0; } while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--; return R; }
xnum operator*(const xnum& A, const int B) ^9 E6 V- W- L' P- L* h7 ?" l/ z { int I;1 D6 j' x, X2 N if (B == 0) return 0;5 V% |% s, ~# R: `7 B6 @+ h" X xnum R; hugeint Carry = 0; for (I = 0; I < A.Len || Carry > 0; I++) {8 M9 e, E1 [" N$ f6 `, d4 N if (I < A.Len) Carry += hugeint(A[I]) * B;6 [% I" q2 e9 c9 V% B+ A' b R[I] = Carry % Base;3 U1 M8 Q8 d% `7 f# B8 b1 G Carry /= Base;5 w( g1 p& S( ^4 B0 Z/ W; G. N }' Z8 r; I0 ~/ s- [& @4 P$ S) x9 {9 W R.Len = I; return R; }
xnum operator*(const xnum& A, const xnum& B)' S* i% s4 u/ @- X$ A) V {$ a2 { d( r! C \( Z: x) @! F int I;1 ^1 z8 D& W' ?! z( ]4 L* { if (B.Len == 0) return 0; xnum R;& C) H; z; F8 m6 u for (I = 0; I < A.Len; I++) { hugeint Carry = 0;& `! ^( D. ^' j$ r9 }# l for (int J = 0; J < B.Len || Carry > 0; J++)' Q9 l( a8 S' o$ t1 y; h { if (J < B.Len) Carry += hugeint(A[I]) * B[J]; if (I + J < R.Len) Carry += R[I + J]; if (I + J >= R.Len) R[R.Len++] = Carry % Base;! m, _1 h4 o2 J2 _ else R[I + J] = Carry % Base; Carry /= Base; } }- Q* A) ]- c+ L3 j* o9 U& ?( C/ b return R; }
xnum operator/(const xnum& A, const int B) {5 H! E; d" Q" M: {/ w e8 K6 K3 g xnum R; int I; hugeint C = 0; for (I = A.Len - 1; I >= 0; I--) {' d$ o/ E9 e, j. L C = C * Base + A[I];0 n3 |" f( U x$ \ R[I] = C / B; C %= B; } R.Len = A.Len; while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;4 t9 d7 p( v5 T) E; o2 v return R; }
xnum operator/(const xnum& A, const xnum& B) {: u- ~0 |& G; z7 V2 T int I;8 H+ T8 Y7 {5 x" X3 m5 r9 V xnum R, Carry = 0; int Left, Right, Mid; for (I = A.Len - 1; I >= 0; I--) { Carry = Carry * Base + A[I]; Left = 0; Right = Base - 1;5 _7 B3 W: G3 Y6 m( G$ \2 G8 G$ H while (Left < Right)$ h8 D0 H. N/ W( i; H" _ {4 t: A6 n7 ?2 ?6 C+ w Mid = (Left + Right + 1) / 2; if (compare(B * Mid, Carry) <= 0) Left = Mid;) o+ S [" R0 h$ U+ S3 w9 { else Right = Mid - 1; }' ^0 N& ]3 E! v+ s8 M4 z7 M R[I] = Left;/ K* I- @+ B+ R6 ^) A( A8 v1 x Carry = Carry - B * Left; } R.Len = A.Len; y+ ?6 l( f8 ?0 C9 K& D. l while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--; return R; } xnum operator%(const xnum& A, const xnum& B)' Q5 h N" G6 X, i1 ?2 s1 ]) X | { int I; xnum R, Carry = 0;6 P3 ~. V; m$ ]; L0 q0 G int Left, Right, Mid;) y% n1 ~ _5 T for (I = A.Len - 1; I >= 0; I--)/ M6 K8 {& e& \5 Q4 `; I {3 C) A4 L3 E1 N$ Q R6 e Carry = Carry * Base + A[I]; Left = 0; Right = Base - 1;2 G! u) L9 k5 Z1 d, L, } while (Left < Right)% C; X+ b/ H- [, C: ?( A { Mid = (Left + Right + 1) / 2;- `3 N! {+ `2 \ if (compare(B * Mid, Carry) <= 0) Left = Mid;+ p4 ?) W, S# F" ^: r else Right = Mid - 1; }+ v1 p0 U/ \$ r" _: b+ v0 v/ Z5 Q+ l' q% a R[I] = Left; Carry = Carry - B * Left;& L0 _. ]8 j/ q: d } R.Len = A.Len;: t& b/ l, }: u7 b ]' O while (R.Len > 0 && R[R.Len - 1] == 0) R.Len--;, I6 U4 v) k4 p- B return Carry;" e+ p; }4 h1 A0 R" s9 B3 Q }
istream& operator>>(istream& In, xnum& V) {6 L8 v% W) g* Q& e% p3 Z; H char Ch;$ l" y! [2 y6 R9 Z, Q4 L9 x1 t for (V = 0; In >> Ch;)2 Y5 n: D# M3 P! d8 e { V = V * 10 + (Ch - '0');; Q, S3 ]& n, D4 g8 u$ G# z+ q! ^/ r e if (cin.peek() <= ' ') break;0 U# `8 n; q* X }% [0 {3 |2 I, Z return In;& H) k+ \0 j! H }
ostream& operator<<(ostream& Out, const xnum& V)7 A4 `* F; }; K! [ z+ c6 _7 i { int I; Out << (V.Len == 0 ? 0 : V[V.Len - 1]);% [ Z6 J) {& d- c for (I = V.Len - 2; I >= 0; I--) for (int J = Base / 10; J > 0; J /= 10) Out << V[I] / J % 10;9 j: C- l. K8 J8 \: |8 _ return Out;; W6 A! k8 n- D& H; M }, e% \9 @ J3 N+ a2 `& h
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |