(*//
标题:无限进制处理
说明:使用于数学领域进制之间相互转换和计算
设计:Zswang
日期:2005-01-15
支持:wjhu111@21cn.com
//*)
uses Math;
const
cScaleChar: array[0..35] of Char = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
function StringToCharSet( //字符串集合
mString: string //源字符串
): TSysCharSet; //返回字符串中包含的集合
var
I: Integer;
begin
Result := [];
for I := 1 to Length(mString) do Include(Result, mString[I]);
end; { StringToCharSet }
function StrLeft( //取左边的字符串
mStr: string; //原字符串
mDelimiter: string; //分隔符
mIgnoreCase: Boolean = False //是否忽略大小写
): string; //返回第一个分隔符左边的字符串
begin
if mIgnoreCase then
Result := Copy(mStr, 1, Pos(UpperCase(mDelimiter), UpperCase(mStr)) - 1)
else Result := Copy(mStr, 1, Pos(mDelimiter, mStr) - 1);
end; { StrLeft }
function StrRight( //取右边的字符串
mStr: string; //原字符串
mDelimiter: string; //分隔符
mIgnoreCase: Boolean = False //是否忽略大小写
): string; //返回第一个分隔符右边的字符串
begin
if mIgnoreCase then
begin
if Pos(UpperCase(mDelimiter), UpperCase(mStr)) > 0 then
Result := Copy(mStr, Pos(UpperCase(mDelimiter), UpperCase(mStr)) +
Length(mDelimiter), MaxInt)
else Result := '';
end else
begin
if Pos(mDelimiter, mStr) > 0 then
Result := Copy(mStr, Pos(mDelimiter, mStr) + Length(mDelimiter), MaxInt)
else Result := '';
end;
end; { StrRight }
function IntegerFullZero( //对齐前补0
mInteger: string; //整数字符串
mLength: Integer //总长度
): string; //返回补0后的整数字符串
begin
Result := StringOfChar('0', mLength - Length(mInteger)) + mInteger;
end; { IntegerFullZero }
function IntegerCompare( //比较两个整数
mIntegerA: string; //整数1
mIntegerB: string //整数2
): Integer; //返回比较的值 +1、0、-1
var
I: Integer;
begin
I := Max(Length(mIntegerA), Length(mIntegerB)); //整数部分最大
mIntegerA := IntegerFullZero(mIntegerA, I);
mIntegerB := IntegerFullZero(mIntegerB, I);
Result := CompareText(mIntegerA, mIntegerB);
end; { IntegerCompare }
function IntegerFormat( //清除无效的0
mInteger: string //整数字符串
): string; //返回处理后的整数字符串
begin
Result := UpperCase(mInteger);
if Result = '' then Result := '0';
while (Pos('0', Result) = 1) and (Result <> '0') do Delete(Result, 1, 1); //排除整数前无效的0
end; { IntegerFormat }
function IntegerAdd( //无限整数加法
mIntegerA: string; //整数1
mIntegerB: string; //整数2
mScale: Byte = 10 //进制
): string; //返回两个整数的和
var
I: Integer;
T: Integer;
begin
Result := '';
if mScale < 2 then Exit;
mIntegerA := IntegerFormat(mIntegerA);
mIntegerB := IntegerFormat(mIntegerB);
if StringToCharSet(mIntegerA + mIntegerB) -
[cScaleChar[0]..cScaleChar[mScale - 1]] <> [] then Exit;
I := Max(Length(mIntegerA), Length(mIntegerB)); //整数部分最大
mIntegerA := IntegerFullZero(mIntegerA, I); //对齐前补0
mIntegerB := IntegerFullZero(mIntegerB, I); //对齐前补0
T := 0; //进位数初始
for I := I downto 1 do //从后向前扫描
begin
T := (Pos(Copy(mIntegerA, I, 1), cScaleChar) - 1) + T; //累加当前数位
T := (Pos(Copy(mIntegerB, I, 1), cScaleChar) - 1) + T; //累加当前数位
Result := cScaleChar[T mod mScale] + Result; //计算当前数位上的数字
T := T div mScale; //计算进位数
end;
if T <> 0 then Result := cScaleChar[T mod mScale] + Result; //处理进位数
while (Pos('0', Result) = 1) and (Result <> '0') do Delete(Result, 1, 1); //排除整数前无效的0
end; { IntegerAdd }
function IntegerSub( //无限整数减法
mIntegerA: string; //整数1
mIntegerB: string; //整数2
mScale: Byte = 10 //进制
): string; //返回两个整数的积
var
I: Integer;
T: Integer;
begin
Result := '';
if mScale < 2 then Exit;
mIntegerA := IntegerFormat(mIntegerA);
mIntegerB := IntegerFormat(mIntegerB);
if StringToCharSet(mIntegerA + mIntegerB) -
[cScaleChar[0]..cScaleChar[mScale - 1]] <> [] then Exit;
I := Max(Length(mIntegerA), Length(mIntegerB)); //整数部分最大
mIntegerA := IntegerFullZero(mIntegerA, I); //对齐前补0
mIntegerB := IntegerFullZero(mIntegerB, I); //对齐前补0
if mIntegerA < mIntegerB then Exit;
T := 0; //进位数初始
for I := I downto 1 do //从后向前扫描
begin
T := (Pos(Copy(mIntegerA, I, 1), cScaleChar) - 1) - T; //累加当前数位
T := T - (Pos(Copy(mIntegerB, I, 1), cScaleChar) - 1); //累加当前数位
Result := cScaleChar[(T + mScale) mod mScale] + Result; //计算当前数位上的数字
if T >= 0 then T := 0 else T := 1;
end;
while (Pos('0', Result) = 1) and (Result <> '0') do Delete(Result, 1, 1); //排除整数前无效的0
end; { IntegerSub }
function IntegerMult( //无限整数乘法
mIntegerA: string; //整数1
mIntegerB: string; //整数2
mScale: Byte = 10 //进制
): string; //返回两个整数的积
function fMult( //无限位数乘法子函数
mInteger: string; //整数
mByte: Byte //位数
): string; //返回位数和整数的积
var
I: Integer;
T: Integer;
begin
Result := '';
T := 0;
for I := Length(mInteger) downto 1 do //从后向前扫描
begin
T := (Pos(Copy(mInteger, I, 1), cScaleChar) - 1) * mByte + T; //累加当前数位
Result := cScaleChar[T mod mScale] + Result; //计算当前数位上的数字
T := T div mScale; //计算进位数
end;
if T <> 0 then Result := cScaleChar[T mod mScale] + Result; //处理进位数
end; { fMult }
var
I: Integer;
T: string;
begin
Result := '';
if mScale < 2 then Exit;
mIntegerA := IntegerFormat(mIntegerA);
mIntegerB := IntegerFormat(mIntegerB);
if StringToCharSet(mIntegerA + mIntegerB) -
[cScaleChar[0]..cScaleChar[mScale - 1]] <> [] then Exit;
T := '';
for I := Length(mIntegerB) downto 1 do
begin
Result := IntegerAdd(Result,
fMult(mIntegerA, (Pos(Copy(mIntegerB, I, 1), cScaleChar) - 1)) + T, mScale);
T := T + '0';
end;
Result := IntegerFormat(Result);
end; { InfiniteMult }
function IntegerDivMod( //无限整数除法
mIntegerA: string; //整数1
mIntegerB: string; //整数2
var nDiv: string; //返回除数
var nMod: string; //返回余数
mScale: Byte = 10 //进制
): Boolean; //返回两个整数的积
var
T: string;
K: string;
begin
Result := False;
if mScale < 2 then Exit;
mIntegerA := IntegerFormat(mIntegerA);
mIntegerB := IntegerFormat(mIntegerB);
if StringToCharSet(mIntegerA + mIntegerB) -
[cScaleChar[0]..cScaleChar[mScale - 1]] <> [] then Exit;
if mIntegerB = '0' then Exit;
Result := True;
nDiv := '0';
while IntegerCompare(mIntegerA, mIntegerB) >= 0 do
begin
T := mIntegerB;
K := '1';
while IntegerCompare(mIntegerA, T + '0') >= 0 do
begin
T := T + '0';
K := K + '0';
end;
mIntegerA := IntegerSub(mIntegerA, T, mScale);
nDiv := IntegerAdd(nDiv, K, mScale);
end;
nMod := mIntegerA;
end; { IntegerDivMod }
function IntegerFactorial( //无限整数的阶乘
mInteger: Integer; //整数
mScale: Byte = 10 //进制
): string; //返回整数的阶乘
var
I: Integer;
T: string;
begin
Result := '';
if mScale < 2 then Exit;
Result := '1';
T := '0';
for I := 1 to mInteger do
begin
T := IntegerAdd(T, '1', mScale);
Result := IntegerMult(Result, T, mScale);
end;
end; { InfiniteFactorial }
function IntegerPower( //无限整数的次方
mBase: string; //指数
mExponent: Integer; //幂数
mScale: Byte = 10 //进制
): string; //返回Base的Exponent次方
var
I: Integer;
begin
Result := '';
if mScale < 2 then Exit;
mBase := IntegerFormat(mBase);
if StringToCharSet(mBase) -
[cScaleChar[0]..cScaleChar[mScale - 1]] <> [] then Exit;
Result := '1';
for I := 1 to mExponent do
Result := IntegerMult(Result, mBase, mScale);
end; { IntegerPower }
function IntegerDigit( //进制间的转换
mIntegerFrom: string; //来源整数
mScaleFrom: Byte; //来源进制
mScaleTo: Byte //目标进制
): string; //返回处理后的整数字符串
function fIntegerDigit( //进制间的转换
mIntegerFrom: Char //来源整数
): string; //返回处理后的整数字符串
var
T: string;
begin
Result := '0';
T := '0';
while IntegerCompare(T, mIntegerFrom) < 0 do
begin
Result := IntegerAdd(Result, '1', mScaleTo);
T := IntegerAdd(T, '1', mScaleFrom);
end;
end;
var
I, L: Integer;
vBase: string;
T: string;
begin
Result := '';
if (mScaleFrom < 2) or (mScaleTo < 2) then Exit;
mIntegerFrom := IntegerFormat(mIntegerFrom);
if StringToCharSet(mIntegerFrom) -
[cScaleChar[0]..cScaleChar[mScaleFrom - 1]] <> [] then Exit;
if mScaleFrom = mScaleTo then
begin
Result := mIntegerFrom;
Exit;
end;
Result := '0';
if mIntegerFrom = '0' then Exit;
vBase := '1';
T := '1';
while IntegerCompare(T, cScaleChar[mScaleFrom - 1]) <= 0 do
begin
vBase := IntegerAdd(vBase, '1', mScaleTo);
T := IntegerAdd(T, '1', mScaleFrom);
end;
L := Length(mIntegerFrom);
for I := 1 to L do
begin
Result := IntegerAdd(
Result,
IntegerMult(
fIntegerDigit(
mIntegerFrom[L - I + 1]
),
IntegerPower(
vBase,
I - 1,
mScaleTo
),
mScaleTo)
mScaleTo
);
end;
end; { IntegerDigit }
function Numberexpression_r(mNumber: string): string;
var
vExponent: Integer;
vBase: string;
L: Integer;
begin
Result := '';
vBase := StrLeft(mNumber, 'e', True);
vExponent := StrToIntDef(StrRight(mNumber, 'e', True), 0);
L := Length(StrRight(vBase, '.'));
vBase := StringReplace(vBase, '.', '', [rfReplaceAll]);
Result := vBase + StringOfChar('0', vExponent - L);
end; { NumberExpression }
//Example
procedure TForm1.Edit1Change(Sender: TObject);
var
vDiv, vMod: string;
begin
Edit3.Text := IntegerAdd(Edit1.Text, Edit2.Text, 10);
Edit4.Text := IntegerMult(Edit1.Text, Edit2.Text, 10);
Edit5.Text := IntegerSub(Edit1.Text, Edit2.Text, 10);
IntegerDivMod(Edit1.Text, Edit2.Text, vDiv, vMod, 10);
Edit6.Text := vDiv;
Edit7.Text := vMod;
Edit8.Text := IntegerDigit(Edit1.Text, 36, 23);
Edit9.Text := IntegerDigit(Edit8.Text, 23, 36);
CheckBox1.Checked :=
IntegerCompare(IntegerAdd(IntegerMult(vDiv, Edit2.Text), vMod), Edit1.Text) = 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Text := IntegerFactorial(1000, 20); // 计算1000的阶乘用20进制表示
end;