Author Topic: Math with Very large numbers using Strings  (Read 2534 times)

I've heard of a method of doing math on very large numbers using strings, by turning the pen-and-paper math methods into functions that input strings that have numbers in them, and output the correct result.
I've tryed making an addition function, but it diddnt turn out so well.

Does anyone know how to make working addition, subtraction, multiplication, and (possibly) division? (to a specefied number of decimal places)

idk if this is what your looking for, but I found this.
Code: [Select]
function StringMath(%str)
{
for(%i=0;%i<getWordCount(%str);%i++)
{
if(getWord(%str,%i) != getWord(%str,%i) * 1)
{
%nextnum = getWord(%str,%i);
%math = %math SPC %nextnum;
if(getWord(%math,%i - 1) != getWord(%math,%i - 1) * 1)
{
switch$(getWord(%math,%i - 1))
{
case "+":
%answer = %answer + %nextnum;
case "-":
%answer = %answer - %nextnum;
case "*":
%answer = %answer * %nextnum;
case "/":
%answer = %answer / %nextnum;
}
}
}
else
%math = %math SPC getWord(%str,%i);
}
}

Not tested but should work
By Brian Smith :)
Got it from his calculator.

Not what i'm looking for...
functions, 2 arguments.
works on a char-by-char basis.
seperate functions for addition, subtraction, multiplication, and division (if possible).

Not what i'm looking for...
functions, 2 arguments.
works on a char-by-char basis.
seperate functions for addition, subtraction, multiplication, and division (if possible).
What
you mean like
Code: [Select]
function Add(%str1,%str2)
{
return %str1 + %str2;
}

function Subtract(%str1,%str2)
{
return %str1 - %str2;
}
function Mulitply(%str1,%str2)
{
return %str1 * %str2;
}
function Divide(%str1,%str2)
{
return %str1 / %str2;
}
or like
Code: [Select]
function MathFunction(%numbers,%type)
{
switch$(%type)
{
case "+":
for(%i=0;%i<getWordCount(%numbers);%i++)
{
%answer = %answer + getWord(%numbers,%i);
}
case "-":
for(%i=0;%i<getWordCount(%numbers);%i++)
{
%answer = %answer - getWord(%numbers,%i);
}
case "*":
for(%i=0;%i<getWordCount(%numbers);%i++)
{
%answer = %answer * getWord(%numbers,%i);
}
case "/":
for(%i=0;%i<getWordCount(%numbers);%i++)
{
%answer = %answer / getWord(%numbers,%i);
}
}
return %answer;
}
Idk what your asking for.

He's asking for a function like this:
Code: [Select]
function add( %a, %b )
{
    return ( any method of adding %a and %b together without using the + operator );
}

Quark is working on something like this, I'll get back to you if he reaches any significant progress.
I don't know if that's any help, but I thought about something like converting the two numbers to binary, doing binary math (which is a quite simple logical progress) and converting them back. I'm not sure if that's a good solution though.

I don't know if that's any help, but I thought about something like converting the two numbers to binary, doing binary math (which is a quite simple logical progress) and converting them back. I'm not sure if that's a good solution though.
How the hell would that work? Binary and bitwise operations are expressed as decimal numbers in Torque. Unless you mean a string of 1s and 0s.

EDIT: This seems to work...
Code: [Select]
function setSubStr(%string,%start,%value) //support function for settings characters or sub strings in strings
{
return getSubStr(%string,0,%start) @ %value @ getSubStr(%string,%start + strLen(%value),strLen(%string));
}
function mBigAdd(%value,%other)
{
%numbers = "0123456789";

%length1 = strLen(%value);
%length2 = strLen(%other);

for(%i=0;%i<%length2;%i++) //loop forwards
{
%number2 = getSubStr(%other,%length2 - %i - 1,1);

if(%i >= %length1) // we don't have a column for this, so just append it at the front
{
if(%number2 $= "0") //so we don't get 010 + 10 = 020, but rather 20
continue;

%value = %number2 @ %value;

continue;
}

%number1 = getSubStr(%value,%length1 - %i - 1,1);

if(strPos(%numbers,%number1) == -1 || strPos(%numbers,%number2) == -1) //not a number character, continue
continue;

%new = %number1 + %number2; //add the two one digit numbers together

if(%new > 9) //reached above 10, need to carry this over to the next column of digits
{
%next = %length1 - %i - 2; //next column index in the string
%value = setSubStr(%value,%length1 - %i - 1,%new - 10); //set the value of the current column to the digits that go over 10

if(%next < 0) //next column doesn't exist, so just append 1 to the start of the string (example, 923 + 923 -> 1846)
{
%value = 1 @ %value;

continue;
}

%value = setSubStr(%value,%next,getSubStr(%value,%next,1) + 1);
}
else //not carrying over, we can simply change the character
%value = setSubStr(%value,%length1 - %i - 1,%new);
}

return %value;
}
It's really scrubby, I just put it together quickly I'll clean it up and add a subtract thing some other time
« Last Edit: November 10, 2011, 01:59:51 AM by Destiny/Zack0Wack0 »

How the hell would that work? Binary and bitwise operations are expressed as decimal numbers in Torque. Unless you mean a string of 1s and 0s.

-snip-
i mean strings of numbers, you know;
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
like
echo(4872984723894723400478120); will give a scientific notation rounded number
echo("4872984723894723400478120"); will give the entire numbers, because strings aren't limited.

Probably easier to just parse it and handle it the elementary school way. Having pretty big numbers could result in a long string in binary form, although I doubt it's going to hit the character limit (can't remember it, something like 4096 I think?), but yeah.

i mean strings of numbers, you know;
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
like
echo(4872984723894723400478120); will give a scientific notation rounded number
echo("4872984723894723400478120"); will give the entire numbers, because strings aren't limited.
He understood what you meant, he was answering me.

Fixed a bug with my script (I forgot to make values at index 0 that go over 9 append to the beginning of the string), added an insight into what the hell is going on and added the setSubStr support function I forgot to include. Seems to work perfectly now.
« Last Edit: November 10, 2011, 02:00:22 AM by Destiny/Zack0Wack0 »

I'll save you guys some of the hassle here.

This is the script I wrote for unlimited mining to handle VERY large numbers.  It handles up to 20 digits with no problems.  In theory it will handle an unlimited but 20 is the max thats been used in my server.
you can do add, subtract, greater than and less than.  no multiply, no divide.

to use:
echo( BigNumberFromString("1234567890123").add("1234567").display() );

gives this:
1234569124690

where normally you would see:
echo(1234567890123+1234567);
1.91351e+009

in a script:
Code: [Select]
%money = BigNumberFromString(  some really big number here );
%money.add( another really big number );
echo(%money.display() );
%money.subtract("50000000000000000000");
echo(%money.display() );

Allright, I managed to make a working bare-bones addition function (in other words, no decimals, and no negatives) and i'll post the (heavily commented) code for reference if anyone wants to see it.
I'll be working on multiplication next, which is unfourtanetly much harder than addition.
Also, Red_Guy, if you would like, we could collaborate and make a division function.
PS: why is it required to have a function create a number from a string? the engine does that automatically.
and how many lines are your functions? I cant view the file because im using a DSi.
« Last Edit: November 12, 2011, 10:03:40 PM by Ipquarx »


Also, Red_Guy, if you would like, we could collaborate and make a division function.
PS: why is it required to have a function create a number from a string? the engine does that automatically.
and how many lines are your functions? I cant view the file because im using a DSi.
The big numbers are stored as script objects - not strings. thats why you need a function to create a number.  I also use a function because when the engine creates a number from a really long string, it changes it into scientific notation and that messes everything up -- which is the whole point behind writing your own math functions.

Also its a good idea to write a simple method to test your add/subtract functions to make sure they are getting the right answer when you change/tweak stuff

The file has 505 lines in it.  not really that big when compared to other files.

Multiply & divide would be really nice to have. let me know if you get anywhere on that part.

Numbers stored in Scriptobjects eh...
Mine does not use scriptobjects, allthough I could use one to store the functions, mine is just using strings, simply strAdd("235787448", "31364973"); and it will return the answer in about 50 lines of code without cleaning up, and with all the comments.
Allthough its strange, when i try to open the cs, it says it's a .ogg file.

Numbers stored in Scriptobjects eh...
Mine does not use scriptobjects, allthough I could use one to store the functions, mine is just using strings, simply strAdd("235787448", "31364973"); and it will return the answer in about 50 lines of code without cleaning up, and with all the comments.
well the script object makes it easier to store stuff about the number: +/- and such
I also split the number into groups of 5 digits and let torque do the math on the smaller groups - makes it much faster when you have a lot of numbers to add, or have to add to the big number really fast.

Try these with your script and see what you get:
strAdd("100","100")
strAdd("100000", "100000")
strAdd("100", "-50")
strAdd("100", "-100")
strAdd("100000", "-50000")
strAdd("100000", "-100000")


Quote
Allthough its strange, when i try to open the cs, it says it's a .ogg file.
Sounds like your browser is messed up. 
Try "save as" ?

strAdd("100", "-50")
strAdd("100", "-100")
strAdd("100000", "-50000")
strAdd("100000", "-100000")
Those are what are called "Sign Rules", adding a positive and a negative number is really just subtracting, and i have yet to do the Subtraction function. In other words, only Positives will work.
I found a online application that adds 2 very large random numbers together, and i'm testing it using that as I speak.
But just for some confirmation; It does work correctly.
Sounds like your browser is messed up.  
Try "save as" ?
It's a DSi. I can't "Save As" unfourtanetly.

EDIT: I just looked at your script... Almost none of that ScriptObject stuff is needed. My adding code is only 29 lines (without decimals).
Here it is, and it works 100%. If you wanna test it; try adding "32412345673735723456126234763 4" and "12652357348634652345132465674 7", it should come out as:
45064703022370375801258700438 1
And also, equ0s is a function to equal out the length of the 2 strings, like
21287345 and
        923
would become
21287345 and
00000923

Although im not 100% sure that's nessesary, because it might display as false, which displays as 0.
Code: [Select]
function stringAdd(%num1, %num2)
{
if(!(isValidInteger(%num1) && isValidInteger(%num2)))
return "invalidNumber";
%num1 = getWord(equ0s(%num1, %num2), 0);
%num2 = getWord(equ0s(%num1, %num2), 1);
for(%a=0;%a<strLen(%num1);%a++)
{
%start[%a] = getSubStr(%num1, %a, 1);
%adder[%a] = getSubStr(%num2, %a, 1);
}
%Length = strLen(%num1);
for(%a = %Length - 1; %a >= 0; %a--)
{
%res = %start[%a] + %adder[%a] + %Carry;
if(%res > 9 && %a != 0)
{
%Carry = 1;
%Ans[%a] = %res - 10;
continue;
}
if(%res < 10)
%Carry = 0;
%Ans[%a] = %res;
}
for(%a = 0; %a < %length; %a++)
%Answer = %Answer @ %Ans[%a];
return %Answer;
}
« Last Edit: November 13, 2011, 11:32:46 AM by Ipquarx »