Huge amount in delphi

I am writing a program and I multiply numbers by 5 ... For example:

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

But when I compile and run my program, I get an overflow error. How can I solve this problem?

+4
source share
3 answers

The correct value of k will be at least 5 ^ 20,000,000, or 2 ^ 48,000,000. No integer type on the computer can save it; which is 48,000,000 bits, for a loud scream. Even if you store it in binary format, it will require 6,000,000 bytes - 5.7 MB to store it. Your only hope is archival libraries of accuracy, and good luck with that.

What are you trying to calculate? What you are doing right now is calculating a sequence of numbers (k), where the ith element is at least 5 i. This will not work until i = 20,000,000 unless you use other types of variables ...

+6
source

Doing 2 billion multiplications by huge numbers in one thread? If you do not have an ultra-modern overclocked processor cooled by liquid helium, you will have to wait until this is over. However, if you have one, you just have to wait a very long time.

See which search engines returned:

if you're lucky, one of them should be enough for this atrocity. If not, good luck finding something.

+3
source

@Patrick87 is right; no integer type on a computer can contain such a number.
@AlexanderMP is also right; you have to wait a very long time for this to end.

Ignoring all this, I think you are asking for a way to handle an extremely large number that will not fit into an integer variable.
I had a similar problem many years ago, and this is how I dealt with it ...

Return to the basics and figure out the answer as if you were doing this with a pencil and paper. Use string variables to store the textual representation of your numbers and create functions that will add and multiply these strings. You already know the algorithms, you learned about this in childhood.

If you have two functions: MultiplyNumStrings (Str1, Str2) and AddNumStrings (Str1, Str2), your code example will look similar, except that K is now a string, not an int64:

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

This function will add two numbers, which are represented by their string digits:

 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; 

This function will multiply two numbers, which are represented by their string digits:

 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; 

Example: we know that the maximum value for int64 is 9223372036854775807.
If we multiply 9223372036854775807 x 9223372036854775807 using the procedure described above, we get 85070591730234615847396907784232501249.

Pretty cool, huh?

+3
source

All Articles