我正在使用UInt64
达到我的极限,我想知道是否有功能可以执行简单的操作选项,例如+/-等,只需要字符串,因为它们可以存储与您一样多的RAM ......(理论上)
例如我想计算
24758800785707605497982484480
+ 363463464326426
并将结果作为字符串。
我知道如何使用数字系统0123456789
解决字符串问题,并逐字逐句地溢出下一个位置 - 这将耗费更多的力量,但我不介意这个问题...
我想有这种能力进行这样的计算,直到我的RAM爆炸(这将是真正的限制......)
是否有这样的功能已经做到了?
答案 0 :(得分:2)
Delphi中的语言级别不支持任意大整数,但谷歌搜索中出现http://www.delphiforfun.org/programs/Library/big_integers.htm,这可以支持它们作为图书馆。
答案 1 :(得分:1)
在超级计算机上,其称为BCD数学(二进制编码的十进制)和RAM的每个半字节表示十进制数字[0..9] - 不是RAM的有效使用,但是大量计算花费的时间最少(即约3 mSecs乘以200万位数字。快速PC上的BCD仿真器需要5或6分钟。
我永远不需要添加大数字,但我会增加。实际上我迭代地调用这个例程来计算例如1000000阶乘(5,565,709百万个数字答案.Str6Product指的是它如何砍掉一对字符串数.s1和s2的实际长度限制大约是2 ^ 31。函数是受到“字符串可以容纳”的限制。无论那个限制是什么,我都没有到过那里。
// ============================================= =================================
function Str6Product(s1: string; s2: string): string; // 6-13 5:15 PM
var
so,snxt6 : string;
z1,z3, i, j, k : Cardinal; // Cardinal is 32-bit unsigned
x1,x3,xm : Cardinal;
countr : Cardinal;
a1, a2, a3 : array of Int64;
inum, icarry : uInt64; // uInt64 is 64-bit signed
begin
s1 := '00000'+s1;
s2 := '00000'+s2;
z1 := length(s1); // set size of Cardinal arrays
z3 := z1 div 6;
x1 := length(s2); // set size of Cardinal arrays
x3 := x1 div 6;
xm := max(x3,z3);
SetLength(a1,xm+1);
SetLength(a2,xm+1);
// try to keep s1 and s2 about the
// same length for best performance
for i := 1 to xm do begin // from rt 2 lft - fill arrays
// with 4-byte integers
if i <= z3 then a1[i] := StrToInt(copy (s1, z1-i*6+1, 6));
if i <= x3 then a2[i] := StrToInt(copy (s2, x1-i*6+1, 6));
if i > z3 then a1[i] := 0;
if i > x3 then a2[i] := 0;
end;
k := max(xm-x3, xm-z3); // k prevents leading zeroes
SetLength(a3,xm+xm+1);
icarry := 0; countr := 0;
icMax := 0; inMax := 0;
for i := 1 to xm do begin // begin 33 lines of "string mult" engine
inum := 0;
for j := 1 to i do
inum := inum + (a1[i-j+1] * a2[j]);
icarry := icarry + inum;
if icMax < icarry then icMax := icarry;
if inMax < inum then inMax := inum;
inum := icarry mod 1000000;
icarry := icarry div 1000000;
countr := countr + 1;
a3[countr] := inum;
end;
if xm > 1 then begin
for i := xm downto k+1 do begin // k or 2
inum := 0;
for j := 2 to i do
inum := inum + (a1[xm+j-i] * a2[xm-j+2]);
icarry := icarry + inum;
if icMax < icarry then icMax := icarry;
if inMax < inum then inMax := inum;
inum := icarry mod 1000000;
icarry := icarry div 1000000;
countr := countr + 1;
a3[countr] := inum;
end;
end;
if icarry >= 1 then begin
countr := countr + 1;
a3[countr] := icarry;
end;
so := IntToStr(a3[countr]);
for i := countr-1 downto 1 do begin
snxt6 := IntToStr(a3[i]+1000000);
so := so+ snxt6[2]+ snxt6[3]+ snxt6[4]+ snxt6[5]+ snxt6[6]+ snxt6[7];
end;
while so[1] = '0' do // leading zeroes may exist
so := copy(so,2,length(so));
result := so;
end;
// ============================================= =================================
测试电话:
StrText:= Str6Product('742136061320987817587158718975871','623450632948509826743508972875');
答案 2 :(得分:0)
我应该补充一点,您应该能够使用相同的方法添加大数字 - 从右到左,将字符串分段为16个字节的块,然后将这些块转换为uInt64变量。首先添加最低有效位,如果它产生第17个字节,则将其转移到第二个最低有效块,将这两个PLUS添加到任何进位等。否则,将每个16字节块转换回字符串并相应地连接。
从整数到字符串的转换,反之亦然是一种痛苦,但对于大数字运算来说是必需的。