1, only the least significant digit is
//considered.
function euclid_gcd_isdigit($Digit)
{
$Digit = (string)$Digit;
//If the string has zero length, this is an error condition and return 0.
$Length = strlen($Digit);
if ($Length==0)
{
return(0);
}
//Obtain the trailing character of the string.
$Trailing_char = Substr($Digit, $Length-1, 1);
//Do a switch and return an integer based on the character.
switch($Trailing_char)
{
case "9":
return 1;
break;
case "8":
return 1;
break;
case "7":
return 1;
break;
case "6":
return 1;
break;
case "5":
return 1;
break;
case "4":
return 1;
break;
case "3":
return 1;
break;
case "2":
return 1;
break;
case "1":
return 1;
break;
case "0":
return 1;
break;
default:
return 0;
break;
}
}
//
//
//Returns TRUE if the passed argument is a simple integer (no error
//codes, no commas), or FALSE otherwise.
function euclid_gcd_issimpleint($Intnum)
{
$Intnum = (string)$Intnum;
//If the string has zero length, this is an error condition and return 0.
$Length = strlen($Intnum);
if ($Length==0)
{
return(0);
}
//If the first digit is "0", this must be the only character in the string,
//otherwise there is a leading-zero violation.
if (Substr($Intnum, 0, 1)=="0")
{
if ($Length==1)
{
return 1;
}
else
{
return 0;
}
}
//If the first character is a "-" sign, it may not be the only character,
//and it may not precede a "0" (which would again be a leading 0 violation).
//If it is a "-", we can exclude "0" and parse as a positive.
if (Substr($Intnum, 0, 1)=="-")
{
if ($Length==1)
{
return 0;
}
else
{
if (Substr($Intnum, 1, 1) == "0")
{
//This is illegal (a "-" followed by a "0").
return 0;
}
else
{
//We can just remove the "-" and parse as a positive.
$Intnum = Substr($Intnum, 1, $Length - 1);
$Length--;
}
}
}
//It is known at this point that the length is at least 1 and the leading
//character is not zero. All we need to do at this point is check that each
//and every character is a digit.
for ($index=0; $index < $Length; $index++)
{
if (!euclid_gcd_isdigit(Substr($Intnum, $index, 1)))
return 0;
}
return 1;
}
//
//
//Returns the number of digits in the argument, which must be a valid simple
//integer.
function euclid_gcd_ndigits($Intnum)
{
$Intnum = (string)$Intnum;
if (Substr($Intnum, 0, 1) == "-")
{
$rv = strlen($Intnum) - 1;
}
else
{
$rv = strlen($Intnum);
}
return($rv);
}
//
//
//Given a string, converts the final character to an integer. If the character
//is not a digit, returns 0.
function euclid_gcd_digittoint($Digit)
{
//echo "Digit is: ";
//echo $Digit;
//echo "
";
$Digit = (string)$Digit;
//echo "Digit is: ";
//echo $Digit;
//echo "
";
//If the string has zero length, this is an error condition and return 0.
$Length = strlen($Digit);
//echo "Length is: ";
//echo $Length;
//echo "
";
if ($Length==0)
{
return(0);
}
//Obtain the trailing character of the string.
$Trailing_char = Substr($Digit, $Length-1, 1);
//echo "Trailing char is: ";
//echo $Trailing_char;
//echo "
";
//Do a switch and return an integer based on the character.
//The default case gives 0.
switch($Trailing_char)
{
case "9":
return 9;
break;
case "8":
return 8;
break;
case "7":
return 7;
break;
case "6":
return 6;
break;
case "5":
return 5;
break;
case "4":
return 4;
break;
case "3":
return 3;
break;
case "2":
return 2;
break;
case "1":
return 1;
break;
default:
return 0;
break;
}
}
//Decommanates an integer and removes all other crap without respect for
//whether the commas are in the right place or the integer is syntactically valid.
function euclid_gcd_decommanate(&$arg)
{
$temp = "";
$len = strlen($arg);
for ($i=0; $i<$len; $i++)
{
$c = (string)Substr($arg, $i, 1);
if (euclid_gcd_isdigit($c) || ($c == "-"))
$temp = $temp . $c;
}
$arg = (string)$temp;
}
//Commanates an integer which is assumed to by syntactically correct.
function euclid_gcd_commanate(&$arg)
{
euclid_gcd_decommanate($arg);
$temp = "";
$len = strlen($arg);
for ($i=0; $i<$len; $i++)
{
$c = (string)Substr($arg, $len - $i - 1, 1);
$temp = $c . $temp;
if ($i != ($len-1))
{
if (Substr($arg, $len-$i-2, 1) != "-")
{
if (($i % 3) == 2)
$temp = "," . $temp;
}
}
}
$arg = (string)$temp;
}
function do_header(&$style)
{
$style->header_title("GCD Calculator (Euclid's Algorithm)",
"GCD Calculator",
"This cgi-bin form calculates the greatest common divisor of two positive " .
"integers using " .
"Euclid's classic algorithm.");
}
function do_footer(&$style)
{
$style->hrule_std();
echo "
This utility is powered by the "; echo ". All source code is available "; echo "here.
\n"; $style->footer_std(); } function do_form($N1_refresh, $N2_refresh, $Buttontext, $max_gcd_digits) { echo "\n"; } function do_err_msg($Err_msg) { echo ""; echo $Err_msg; echo "
\n"; } //Main script begins here. // // //Let's agree on a maximum for number of digits in either //of the two arguments. This has been checked out and seems //to be within operational parameters (script won't time out). $max_gcd_digits = 200; // $style = new Stdnwpstyle; //Assign the current style in force. Also, starts the CPU //usage clock. //Do the header unconditionally. The header is always used on this page. do_header($style); // // //If N1 was supplied, decommanate it and be sure it is a string. if (isset($N1)) euclid_gcd_decommanate($N1); //Same for N2. if (isset($N2)) euclid_gcd_decommanate($N2); // //There are a few cases to break into here, and this affects the overall layout of the page. //The header and footer are fixed, but the "guts" will change. if (!isset($N1) && !isset($N2)) { //In this case, we are probably visiting the form for the first time, and have not done a submit. //Just display the form itself. do_form("", "", "Calculate GCD", $max_gcd_digits); } elseif (!isset($N1) && isset($N2)) { //Only $N2 is supplied. do_err_msg("You must supply both N1 and N2 to calculate a GCD. Only N2 was supplied. Please try again."); $style->hrule_std(); euclid_gcd_commanate($N2); do_form("", $N2, "Calculate GCD", $max_gcd_digits); } elseif (isset($N1) && !isset($N2)) { //Only $N1 is supplied. do_err_msg("You must supply both N1 and N2 to calculate a GCD. Only N1 was supplied. Please try again."); $style->hrule_std(); euclid_gcd_commanate($N1); do_form($N1, "", "Calculate GCD", $max_gcd_digits); } elseif (!euclid_gcd_issimpleint($N1) || !euclid_gcd_issimpleint($N2)) { //$N1 and $N2 are both supplied, but one or both is malformed. Need to advise. if (!euclid_gcd_issimpleint($N1) && !euclid_gcd_issimpleint($N2)) { do_err_msg("N1 and N2 are both malformed integers. Choose new values and try again."); $style->hrule_std(); do_form($N1, $N2, "Calculate GCD", $max_gcd_digits); } elseif (!euclid_gcd_issimpleint($N1)) { do_err_msg("N1 is a malformed integer. Choose a new value for N1 and try again."); $style->hrule_std(); euclid_gcd_commanate($N2); do_form($N1, $N2, "Calculate GCD", $max_gcd_digits); } else { do_err_msg("N2 is a malformed integer. Choose a new value for N2 and try again."); $style->hrule_std(); euclid_gcd_commanate($N1); do_form($N1, $N2, "Calculate GCD", $max_gcd_digits); } } elseif ((strlen($N1) > $max_gcd_digits) || (strlen($N2) > $max_gcd_digits)) { if ((strlen($N1) > $max_gcd_digits) && (strlen($N2) > $max_gcd_digits)) { do_err_msg("N1 and N2 are both too long (a " . number_format($max_gcd_digits) . "-digit maximum is " . "in effect). Choose shorter values and try again."); $style->hrule_std(); euclid_gcd_commanate($N1); euclid_gcd_commanate($N2); do_form($N1, $N2, "Calculate GCD", $max_gcd_digits); } elseif (strlen($N1) > $max_gcd_digits) { do_err_msg("N1 is too long (a " . number_format($max_gcd_digits) . "-digit maximum is " . "in effect). Choose a shorter value and try again."); $style->hrule_std(); euclid_gcd_commanate($N1); euclid_gcd_commanate($N2); do_form($N1, $N2, "Calculate GCD", $max_gcd_digits); } else { do_err_msg("N2 is too long (a " . number_format($max_gcd_digits) . "-digit maximum is " . "in effect). Choose a shorter value and try again."); $style->hrule_std(); euclid_gcd_commanate($N1); euclid_gcd_commanate($N2); do_form($N1, $N2, "Calculate GCD", $max_gcd_digits); } } else { //N1 and N2 were both supplied and seem to be valid integers. // //If either integer is negative, make it positive. if (Substr($N1, 0, 1)=="-") $N1 = Substr($N1, 1, strlen($N1)-1); if (Substr($N2, 0, 1)=="-") $N2 = Substr($N2, 1, strlen($N2)-1); //If either is "0", make it "1". if ($N1=="0") $N1 = (string)"1"; if ($N2=="0") $N2 = (string)"1"; //We can now run the external program to do the calculation. $cgi_command_string = "./arith_large_cgi gcd " . $N1 . " " . $N2; //echo "CGI command string is : " . $cgi_command_string . "The greatest common divisor of "; echo $cgi_result[1]; echo " and "; echo $cgi_result[2]; echo " is "; echo $cgi_result[$cgi_result_nelem - 2]; echo ".
\n"; $style->hrule_std(); echo "Notes on the algorithm: \n"; echo "Euclid's classic GCD algorithm was known no later than about 200 B.C. and is documented \n"; echo "at the \n"; echo "Wolfram Research site \n"; echo "and also in Knuth's classic reference work, "; echo "The \n"; echo "Art Of Computer Programming. Euclid's GCD algorithm ends with the GCD being the \n"; echo "last non-zero remainder (in yellow below unless a is a multiple of b).\n"; echo "
\n"; //Assign the table column widths. They are centralized here for easy change. $width[0] = 5; $width[1] = 10; $width[2] = 10; $width[3] = 10; $width[4] = 10; echo "\n";
if ($i==0)
{
echo " Round \n"; } else { euclid_gcd_commanate($cgi_result[$i*5-2]); echo "" . $cgi_result[$i*5-2] . " \n"; } echo " | \n";
echo " \n";
if ($i==0)
{
echo " a \n"; } else { euclid_gcd_commanate($cgi_result[$i*5-1]); echo "" . $cgi_result[$i*5-1] . " \n"; } echo " | \n";
echo " \n";
if ($i==0)
{
echo " b \n"; } else { euclid_gcd_commanate($cgi_result[$i*5]); echo "" . $cgi_result[$i*5] . " \n"; } echo " | \n";
echo " \n";
if ($i==0)
{
echo " a div b \n"; } else { euclid_gcd_commanate($cgi_result[$i*5+1]); echo "" . $cgi_result[$i*5+1] . " \n"; } echo " | \n";
if ($i > 0)
euclid_gcd_commanate($cgi_result[$i*5+2]);
echo " 0) && ($cgi_result[$i*5+2] == $cgi_result[$cgi_result_nelem - 2]))
echo " bgcolor=\"#FFFF00\"";
echo ">\n";
if ($i==0)
{
echo " a mod b \n"; } else { //euclid_gcd_commanate($cgi_result[$i*5+2]); echo "" . $cgi_result[$i*5+2] . " \n"; } echo " | \n";
echo "