MakeWebGames

# Human Math

## Recommended Posts

So, I was talking to someone about the problems with using large numbers and I though, hmmm, why not write a script that does basic math the way a person does. We can (hopefully :P ) do addition, multiplication, subtraction, and division with 100% precision to an extent far far greater than PHP math does (if we had enough time, I'd say our precision is infinite).

Well, I've made an addition module and a multiplication module. Feel free to try out the code, and if you think it will be useful to you, you may use it. You may modify the code, you can sell it, you can do whatever you want with it.

```<?php

set_time_limit(0);
class precisionMath {
\$p1 = strpos(\$v1, '.');
\$p2 = strpos(\$v2, '.');
if (\$p1 !== false) {
\$x1 = substr(\$v1, \$p1 + 1);
\$v1 = substr(\$v1,  0, \$p1);
} else {
\$x1 = 0;
}

if (\$p2 !== false) {
\$x2 = substr(\$v2, \$p2 + 1);
\$v2 = substr(\$v2,  0, \$p2);
} else {
\$x2 = 0;
}

if (\$x1 or \$x2) {
\$x1 = str_split(\$x1);
\$x2 = str_split(\$x2);
\$xc1 = count(\$x1);
\$xc2 = count(\$x2);
if (\$xc1 >= \$xc2) {
for (\$x = 1; \$x <= \$xc1 - \$xc2; \$x++) {
\$x2[] = '0';
}
\$bd = \$x1;
\$cd = \$x2;
} else {
for (\$x = 1; \$x <= \$xc2 - \$xc1; \$x++) {
\$x1[] = '0';
}
\$bd = \$x2;
\$cd = \$x1;
}

\$bd = array_reverse(\$bd);
\$cd = array_reverse(\$cd);

\$last = '';
foreach (\$bd as \$key => \$value) {
if (!isset(\$cd[\$key])) {
break;
} else {
\$bd[\$key] += \$cd[\$key];
if (\$bd[\$key] >= 10) {
\$bd[\$key] -= 10;
if (isset(\$bd[\$key + 1])) {
\$bd[\$key + 1]++;
} else {
\$last = 1;
}
}
}
}
} // End of decimal portion.

\$v1 = str_split(\$v1);
\$v2 = str_split(\$v2);
if (count(\$v1) >= count(\$v2)) {
\$b = \$v1;
\$c = \$v2;
} else {
\$b = \$v2;
\$c = \$v1;
}

\$b = array_reverse(\$b);
\$c = array_reverse(\$c);

if (isset(\$last) and \$last == 1) {
\$b[0]++;
}

\$last = '';
foreach (\$b as \$key => \$value) {
if (!isset(\$c[\$key])) {
break;
} else {
\$b[\$key] += \$c[\$key];
if (\$b[\$key] >= 10) {
\$b[\$key] -= 10;
if (isset(\$b[\$key + 1])) {
\$b[\$key + 1]++;
} else {
\$last = 1;
}
}
}
}

if (isset(\$bd)) {
return \$last . implode(array_reverse(\$b)) . '.' . implode(array_reverse(\$bd));
} else {
return \$last . implode(array_reverse(\$b));
}

}

function mult(\$v1,\$v2) {

\$p1 = strpos(\$v1, '.');
\$p2 = strpos(\$v2, '.');
\$v1_len = strlen(\$v1);
\$v2_len = strlen(\$v2);

if (\$p1 !== false) {
\$p1 = \$v1_len - \$p1 - 1;
\$v1_len--;
\$v1 = str_replace('.', '', \$v1);
} else {
\$p1 = 0;
}

if (\$p2 !== false) {
\$p2 = \$v2_len - \$p2 - 1;
\$v2_len--;
\$v2 = str_replace('.', '', \$v2);
} else {
\$p2 = 0;
}

if (strlen(\$v1) >= strlen(\$v2)) {
\$b = \$v1;
\$c = \$v2;
} else {
\$b = \$v2;
\$c = \$v1;
}
\$c = array_reverse(str_split(\$c));

\$sum = '0';
foreach (\$c as \$key => \$value) {
\$subtotal = '0';
for (\$x = 1; \$x <= \$value; \$x++) {
}
}

if (\$p1 or \$p2) {
\$sum_len = strlen(\$sum);
\$start = substr(\$sum, 0, \$sum_len - \$p);
\$end = substr(\$sum, \$sum_len - \$p);
\$sum = \$start . '.' . \$end;
}

return \$sum;
}

}

\$math = new precisionMath();

\$r3 = \$math->mult('1324751973451345817344593459173457139457934759455714395719345719745917450', '13451749571934751982375172351743571349571935471947591734591734571439571947597459184');

\$r4 = \$math->mult('9874514.1435162451345790234759017345917345971394571934759173459714395719345791475901745', '7830947513454.1834534875074938579304579347698273469723496720937560927569275627681034858345803485');

echo <<<EOT

\$r1

\$r2

Multiplication with no decimals:

\$r3

Multiplication with decimals:

\$r4

EOT;```
##### Share on other sites

Re: Human Math

Update

The previous example did not accept negative numbers. The new one accepts negative numbers in the addition and multiplication methods.

I've also added in a subtraction module, and it also accepts negative numbers.

All three modules accept decimal numbers and negative numbers, or any combination of those.

```<?php

set_time_limit(0);
class precisionMath {

function isNegative(\$value) {
if (strpos(\$value, '-') === 0) {
return true;
} else {
return false;
}
}

function stripNegative(\$value) {
return substr(\$value, 1);
}

if (\$this->isNegative(\$v1)) {
\$v1 = \$this->stripNegative(\$v1);
\$v1_neg = true;
} else {
\$v1_neg = false;
}

if (\$this->isNegative(\$v2)) {
\$v2 = \$this->stripNegative(\$v2);
\$v2_neg = true;
} else {
\$v2_neg = false;
}

if (!\$v1_neg and !\$v2_neg) {
} elseif(\$v1_neg and !\$v2_neg) {
if (\$v1 == \$v2) {
return 0;
} elseif (\$v1 > \$v2) {
\$result = \$this->minus_mechanics(\$v1, \$v2);
return '-' . \$result;
} else {
return \$this->minus_mechanics(\$v2, \$v1);
}
} elseif(!\$v1_neg and \$v2_neg) {
if (\$v1 == \$v2) {
return 0;
} elseif (\$v1 > \$v2) {
return \$this->minus_mechanics(\$v1, \$v2);
} else {
\$result = \$this->minus_mechanics(\$v2, \$v1);
return '-' . \$result;
}
} else {
}

}

\$p1 = strpos(\$v1, '.');
\$p2 = strpos(\$v2, '.');
if (\$p1 !== false) {
\$x1 = substr(\$v1, \$p1 + 1);
\$v1 = substr(\$v1,  0, \$p1);
} else {
\$x1 = 0;
}

if (\$p2 !== false) {
\$x2 = substr(\$v2, \$p2 + 1);
\$v2 = substr(\$v2,  0, \$p2);
} else {
\$x2 = 0;
}

if (\$x1 or \$x2) {
\$x1 = str_split(\$x1);
\$x2 = str_split(\$x2);
\$xc1 = count(\$x1);
\$xc2 = count(\$x2);
if (\$xc1 >= \$xc2) {
for (\$x = 1; \$x <= \$xc1 - \$xc2; \$x++) {
\$x2[] = '0';
}
\$bd = \$x1;
\$cd = \$x2;
} else {
for (\$x = 1; \$x <= \$xc2 - \$xc1; \$x++) {
\$x1[] = '0';
}
\$bd = \$x2;
\$cd = \$x1;
}

\$bd = array_reverse(\$bd);
\$cd = array_reverse(\$cd);

\$last = '';
foreach (\$bd as \$key => \$value) {
if (!isset(\$cd[\$key])) {
break;
} else {
\$bd[\$key] += \$cd[\$key];
if (\$bd[\$key] >= 10) {
\$bd[\$key] -= 10;
if (isset(\$bd[\$key + 1])) {
\$bd[\$key + 1]++;
} else {
\$last = 1;
}
}
}
}
} // End of decimal portion.

\$v1 = str_split(\$v1);
\$v2 = str_split(\$v2);
if (count(\$v1) >= count(\$v2)) {
\$b = \$v1;
\$c = \$v2;
} else {
\$b = \$v2;
\$c = \$v1;
}

\$b = array_reverse(\$b);
\$c = array_reverse(\$c);

if (isset(\$last) and \$last == 1) {
\$b[0]++;
}

\$last = '';
foreach (\$b as \$key => \$value) {
if (!isset(\$c[\$key])) {
break;
} else {
\$b[\$key] += \$c[\$key];
if (\$b[\$key] >= 10) {
\$b[\$key] -= 10;
if (isset(\$b[\$key + 1])) {
\$b[\$key + 1]++;
} else {
\$last = 1;
}
}
}
}

if (isset(\$bd)) {
return \$last . implode(array_reverse(\$b)) . '.' . implode(array_reverse(\$bd));
} else {
return \$last . implode(array_reverse(\$b));
}

}

function minus(\$v1,\$v2) {
if (\$this->isNegative(\$v1)) {
\$v1 = \$this->stripNegative(\$v1);
\$v1_neg = true;
} else {
\$v1_neg = false;
}

if (\$this->isNegative(\$v2)) {
\$v2 = \$this->stripNegative(\$v2);
\$v2_neg = true;
} else {
\$v2_neg = false;
}

if (!\$v1_neg and !\$v2_neg and \$v1 >= \$v2) {
return \$this->minus_mechanics(\$v1,\$v2);
} elseif (!\$v1_neg and !\$v2_neg and \$v1 < \$v2) {
return '-' . \$this->minus_mechanics(\$v2,\$v1);
} elseif(\$v1_neg and !\$v2_neg) {
} elseif(!\$v1_neg and \$v2_neg) {
} else {
if (\$v1 >= \$v2) {
return '-' . \$this->minus_mechanics(\$v1,\$v2);
} else {
return \$this->minus_mechanics(\$v2,\$v1);
}
}

}

function minus_mechanics(\$b,\$c) {

\$p1 = strpos(\$b, '.');
\$p2 = strpos(\$c, '.');
if (\$p1 !== false) {
\$bd = substr(\$b, \$p1 + 1);
\$b = substr(\$b,  0, \$p1);
} else {
\$bd = 0;
}

if (\$p2 !== false) {
\$cd = substr(\$c, \$p2 + 1);
\$c = substr(\$c,  0, \$p2);
} else {
\$cd = 0;
}

if (\$bd or \$cd) {
\$bd = str_split(\$bd);
\$cd = str_split(\$cd);
\$xc1 = count(\$bd);
\$xc2 = count(\$cd);
if (\$xc1 >= \$xc2) {
for (\$x = 1; \$x <= \$xc1 - \$xc2; \$x++) {
\$cd[] = '0';
}
} else {
for (\$x = 1; \$x <= \$xc2 - \$xc1; \$x++) {
\$bd[] = '0';
}
}

\$bd = array_reverse(\$bd);
\$cd = array_reverse(\$cd);

\$last = '';
foreach (\$bd as \$key => \$value) {
//				echo '<pre>' . print_r(\$bd, 1) . '</pre>
';
if (!isset(\$cd[\$key])) {
break;
} else {
\$bd[\$key] -= \$cd[\$key];
if (\$bd[\$key]< 0) {
\$bd[\$key] += 10;
if (isset(\$bd[\$key + 1])) {
\$bd[\$key + 1]--;
} else {
\$last = 1;
}
}
}
}
} // End of decimal portion.

\$b = str_split(\$b);
\$c = str_split(\$c);

\$b = array_reverse(\$b);
\$c = array_reverse(\$c);

if (isset(\$last) and \$last == 1) {
\$b[0]--;
}

\$last = '';
foreach (\$b as \$key => \$value) {
if (!isset(\$c[\$key])) {
break;
} else {

if (\$b[\$key] < \$c[\$key]) {
\$temp_key = \$key;
do {
if (!isset(\$b[\$temp_key + 1])) {
\$temp_key = false;
} elseif (\$b[\$temp_key + 1] == 0) {
\$b[\$temp_key + 1] = 9;
\$temp_key++;
} else {
\$b[\$temp_key + 1]--;
\$temp_key = false;
\$b[\$key] += 10;
}
} while (\$temp_key);
}
\$b[\$key] = \$b[\$key] - \$c[\$key];
//				\$b[\$key] = abs(\$b[\$key] - \$c[\$key]);

}
}
\$b = implode(array_reverse(\$b));
do {
\$length = strlen(\$b);
if (\$length == 1) {
\$zeros = false;
} else {
\$zeros = substr(\$b, 0, 1);
if (\$zeros == 0) {
\$b = substr(\$b, 1);
}
}
} while (\$zeros === '0');

if (isset(\$bd)) {
return \$b . '.' . implode(array_reverse(\$bd));
} else {
return \$b;
}
}

function mult(\$v1, \$v2) {

if (\$this->isNegative(\$v1)) {
\$v1 = \$this->stripNegative(\$v1);
\$v1_neg = true;
} else {
\$v1_neg = false;
}

if (\$this->isNegative(\$v2)) {
\$v2 = \$this->stripNegative(\$v2);
\$v2_neg = true;
} else {
\$v2_neg = false;
}

\$result = \$this->mult_mechanics(\$v1, \$v2);

if (!\$v1_neg and !\$v2_neg or \$v1_neg and \$v2_neg) {
return \$result;
} else {
return '-' . \$result;
}
}

function mult_mechanics(\$v1,\$v2) {

\$p1 = strpos(\$v1, '.');
\$p2 = strpos(\$v2, '.');
\$v1_len = strlen(\$v1);
\$v2_len = strlen(\$v2);

if (\$p1 !== false) {
\$p1 = \$v1_len - \$p1 - 1;
\$v1_len--;
\$v1 = str_replace('.', '', \$v1);
} else {
\$p1 = 0;
}

if (\$p2 !== false) {
\$p2 = \$v2_len - \$p2 - 1;
\$v2_len--;
\$v2 = str_replace('.', '', \$v2);
} else {
\$p2 = 0;
}

if (strlen(\$v1) >= strlen(\$v2)) {
\$b = \$v1;
\$c = \$v2;
} else {
\$b = \$v2;
\$c = \$v1;
}
\$c = array_reverse(str_split(\$c));

\$sum = '0';
foreach (\$c as \$key => \$value) {
\$subtotal = '0';
for (\$x = 1; \$x <= \$value; \$x++) {
}
}

if (\$p1 or \$p2) {
\$sum_len = strlen(\$sum);
\$start = substr(\$sum, 0, \$sum_len - \$p);
\$end = substr(\$sum, \$sum_len - \$p);
\$sum = \$start . '.' . \$end;
}

return \$sum;
}

}

\$math = new precisionMath();

\$r3 = \$math->minus_mechanics('1245735846732546254625472753451346234626526243523451345134623462346234623462643357325472546256257254723255257352', '12457358467325462546254727535732547254625625725472275257256');

\$r4 = \$math->minus_mechanics('1245735846732546254625472753451346234626526243523451345134623462346234623462643357325472546256257254723255257352.1124362546245724572434523456256254625462456254362562562565732457', '12457358467325462546254727535732547254625625725472275257256.94775234523423462543625462546245623456234562345624562456254625623456254625462546245624566246256256');

\$r5 = \$math->mult('1324751973451345817344593459173457139457934759455714395719345719745917450', '13451749571934751982375172351743571349571935471947591734591734571439571947597459184');

\$r6 = \$math->mult('9874514.1435162451345790234759017345917345971394571934759173459714395719345791475901745', '7830947513454.1834534875074938579304579347698273469723496720937560927569275627681034858345803485');

echo <<<EOT

\$r1

\$r2

Subtraction with no decimals:

\$r3

Subtraction with decimals:

\$r4

Multiplication with no decimals:

\$r5

Multiplication with decimals:

\$r6

EOT;

```
##### Share on other sites

Re: Human Math

Sweet work Floydian.

Very well constructed.

Thanks

Re: Human Math

Nice One

##### Share on other sites

Re: Human Math

You're welcome ;)

And thanks for the good words!

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
• Create New...