德尔福的数量巨大

时间:2011-07-31 23:08:40

标签: delphi delphi-7

我正在编写一个程序,我将数字乘以5 ...例如:

var
  i:integer;
  k:int64;
begin
  k:=1;
  for i:=1 to 200000000 do
  begin
    k:=5*(k+2);
  end;
  end;
end.

但是当我编译并启动我的程序时,我收到溢出整数错误。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:6)

k的正确值至少为5 ^ 20,000,000,或2 ^ 48,000,000。计算机上没有整数类型可以存储它;这是48,000,000位,大声喊叫。即使你将它存储在二进制文件中,也需要6,000,000字节 - 5.7 MB - 来存储它。你唯一的希望是精确的仲裁库,祝你好运。

你想要计算什么?你现在正在做的是计算一个数字序列(k),其中第i个元素至少与5 ^ i一样大。除非您使用其他类型的变量,否则这将无法达到i = 20,000,000 ...

答案 1 :(得分:3)

在一个单独的线程中对巨大数字进行20亿次乘法运算? 除非你有一个用液氦冷却的最先进的超频CPU,否则你必须等待很多才能完成。但是,如果你有,你只需要等待很长时间。

了解搜索引擎发布的内容:

如果你很幸运,其中一个应该足以应付这场暴行。如果没有 - 祝你好运。

答案 2 :(得分:3)

@ Patrick87是对的;计算机上没有整数类型可以保存这样的数字 @AlexanderMP也是对的;你必须等待很长时间才能完成。

忽略所有这些,我认为你要求一种方法来处理不适合整数变量的极大数量。
几年前我遇到过类似的问题,这就是我处理它的方式......

回到基础并按照与铅笔和纸张相同的方式计算答案。使用字符串变量来保存数字的文本表示,并创建将添加&的函数。乘以这些字符串。你已经知道算法了,你是小时候学过的。

如果你有两个函数是MultiplyNumStrings(Str1,Str2)& AddNumStrings(Str1,Str2)你的示例代码看起来类似,只是K现在是一个字符串而不是int64:

var
  i : integer;
  k : string;
begin
  k := '1';
  for i:=1 to 200000000 do
  begin
    k := MultiplyNumStrings('5', AddNumStrings(k, '2'));
  end;
end;

此函数将添加两个由其字符串数字表示的数字:

function AddNumStrings (Str1, Str2 : string): string;
var
  i : integer;
  carryStr : string;
  worker : integer;
  workerStr : string;
begin
  Result := inttostr (length(Str1));
  Result := '';
  carryStr := '0';

  // make numbers the same length
  while length(Str1) < length(Str2) do
    Str1 := '0' + Str1;

  while length(Str1) > length(Str2) do
    Str2 := '0' + Str2;

  i := 0;
  while i < length(Str1) do
  begin
    worker := strtoint(copy(Str1, length(str1)-i, 1)) +
              strtoint(copy(Str2, length(str2)-i, 1)) +
              strtoint (carryStr);
    if worker > 9 then
    begin
      workerStr := inttostr(worker);
      carryStr := copy(workerStr, 1, 1);
      result := copy(workerStr, 2, 1) + result;
    end
    else
    begin
      result := inttostr(worker) + result;
      carryStr := '0';
    end;


    inc(i);
  end; { while }
  if carryStr <> '0' then
    result := carryStr + result;
end;

此函数将乘以由其字符串数字表示的两个数字:

function MultiplyNumStrings (Str1, Str2 : string): string;
var
  i, j : integer;
  carryStr : string;
  worker : integer;
  workerStr : string;
  tempResult : string;
begin
  Result := '';
  carryStr := '0';
  tempResult := '';

  // process each digit of str1
  for i := 0 to length(Str1) - 1 do
  begin
    while length(tempResult) < i do
      tempResult := '0' + tempResult;

    // process each digit of str2
    for j := 0 to length(Str2) - 1 do
    begin
      worker := (strtoint(copy(Str1, length(str1)-i, 1)) *
                 strtoint(copy(Str2, length(str2)-j, 1))) +
                strtoint (carryStr);
      if worker > 9 then
      begin
        workerStr := inttostr(worker);
        carryStr := copy(workerStr, 1, 1);
        tempResult := copy(workerStr, 2, 1) + tempResult;
      end
      else
      begin
        tempResult := inttostr(worker) + tempResult;
        carryStr := '0';
      end;
    end; { for }
    if carryStr <> '0' then
      tempResult := carryStr + tempResult;
    carryStr := '0';

    result := addNumStrings (tempResult, Result);
    tempResult := '';
  end; { for }

  if carryStr <> '0' then
    result := carryStr + result;
end;

示例:我们知道int64的最大值是9223372036854775807 如果我们使用上面的例程乘以9223372036854775807 x 9223372036854775807,我们得到85070591730234615847396907784232501249。

非常酷,呵呵?