#!/usr/bin/perl # Michael Tartaglia # convert.cgi # Program takes in a number and converts it to morse code, English, # binary, octal, hexidecimal, and performs a palendrome check. use strict; use CGI ":standard"; require template; require math; my @ones = ("zero","one","two","three","four","five","six","seven", "eight","nine","ten","eleven","twelve","thirteen", "fourteen","fifteen","sixteen","seventeen","eighteen", "nineteen"); my @tens = ("ten","twenty","thirty","forty","fifty","sixty", "seventy","eighty","ninety"); my @tenPow = ("","thousand ","million ","billion ","trillion"); template::startHTML("Freelance Program","Converting Numbers"); # IF A NUMBER IS ENTERED, CONVERT IT AND STORE IT IN SEVERAL VARIABLES, # THEN PRINT RESULTS if ($ENV{'QUERY_STRING'} ne "") { my $number = math::abs(param("number")); my $hex = toHEX($number); my $oct = toOCT($number); my $bin = toBINARY($number); my $bcd = toBCD($number); my $mor = toMORSE($number); my $pal = isPAL($number); my $sci = toSCI($number); my $txt = toText(int(param("number"))); my @fac = getFactors(int(param("number"))); print <
Your number $number translates to:
Hexidecimal: $hex
Octal: $oct
Binary: $bin
BCD: $bcd
Morse: $mor
Scientific: $sci
Factors: @fac
English: \L\u$txt\E
Palendrome? $pal

------- EndOfSEG } # PRINT OUT QUERY BOX print <
Input an integer:
EndOfSeg template::endHTML(); ################################################## # All subroutines read in one variable, which is # the number to convert. Also, all subroutines # return a single result, which converted number. # # EXCEPTION: toTextHundreds, which reads in a 3 # digit number and returns the text equivalent ################################################## ################################################## # All subroutines function relatively similarly as # well. They break off the digits by using the # modulous and subtraction operators to convert. # # See toHex for an example... ################################################## sub toHEX { my $x = int($_[0]); # READ IN NUMBER my $xd= $_[0] - $x; # SEPARATE DECIMAL my $hexi = ""; # INITIAL STRING my @h = qw(0 1 2 3 4 5 6 7 8 9 A B C D E F); do { # GET CHARACTER VIA MODULUS AND APPEND $hexi = $h[($x%16)] . $hexi; # SUBTRACT x%16 FROM x, & DIVIDE x by 16 $x -= ($x%16) if ($x%16 != 0); $x /= 16; } while ($x > 0); return $hexi; } sub toOCT { my $x = int($_[0]); my $o = ""; do { $o = $x%8 . $o; $x -= ($x%8) if ($x%8 != 0); $x /= 8; } while ($x > 0); return $o; } sub toBCD { my $x = int($_[0]); my $binary = ""; my $len; my $i; my $sp = ""; my $binSeg = ""; do { $binSeg = toBINARY($x%10); if (length $binSeg < 4) { $len = length $binSeg; for ($i = 4; $i > $len; --$i) { $binSeg = "0" . $binSeg; } } $x = ($x - ($x%10)) / 10; $binary = $binSeg . $sp . $binary; $sp = " "; } while ($x > 0); return $binary; } sub toBINARY { my $x = int($_[0]); my $binary = ""; do { $binary = (($x % 2) ? "1" : "0") . $binary; --$x if (($x % 2) == 1); $x /= 2; } until ($x <= 0); return $binary; } sub isPAL { my $x = $_[0] . ""; $x =~ s/\.//e; my $x1 = $x; my $x2 = ""; do { $x2 = $x2 . ($x%10); $x -= $x%10; $x /= 10; } while ($x > 0); if ($x1 == $x2) { return "Yes, if decimals are excluded."; } else { return "Nope. Not a perfect one."; } } sub toMORSE { my $x = int($_[0]); my @morse = qw( ----- .---- ..--- ...-- ....- ..... -.... --... ---.. ----. ); my $code = ""; my $sep = ""; do { $code = "$morse[$x%10]$sep$code"; $x -= $x%10; $x /= 10; $sep = " "; } while ($x > 0); if (int($_[0]) < $_[0]) { my $numCOPY = $_[0]; $numCOPY =~ s/^\d+\.//e; $code = $code . " --..-- " . toMORSE($numCOPY); } return "$code"; } sub toSCI { my $x = $_[0]; my $exp = 0; my $out = ""; while ($x > 10) { $x /= 10; ++$exp; } $x = math::round($x*1000) / 1000; $out = $out . $x . " x 10" . "$exp"; return $out; } sub toText { my $num = $_[0]; my $t = ""; my $space = ""; my $numCopy = $num; my $position = 0; my @nSegs; if ($num < 0) { $t .= "negative "; $num = math::abs($num); } for (my $i = 0; $num > 0; $i++) { $nSegs[$i] = $num % 1000; $num = math::floor($num/1000); } $position = scalar(@nSegs) - 1; if ($numCopy == 0) { $t .= $ones[0]; } else { while ($position >= 0) { $space = ($position == 0 ? "" : " "); $t .= toTextHundreds($nSegs[$position]); $t .= $space . $tenPow[$position] if ($nSegs[$position] != 0); --$position; } } return $t; } sub toTextHundreds { my $num2 = $_[0]; my $numCopy2 = $num2; my $t2 = ""; my @n; for (my $i = 0; $i < 3; ++$i) { $n[$i] = $numCopy2%10; $numCopy2 = math::floor($numCopy2/10); } if ($num2 == 0) { return $t2; } elsif ($num2 < 20 && $num2 > 0) { $t2 .= $ones[$num2]; } elsif ($num2 < 100 && $num2%10 == 0) { $t2 .= $tens[($num2/10)-1]; } elsif ($num2 >= 100 && $num2%100 == 0) { $t2 .= $ones[$n[2]] . " hundred"; } elsif ($num2 < 100) { $t2 .= $tens[$n[1]-1] . "-" . $ones[$n[0]]; } else { $t2 .= $ones[$n[2]] . " hundred "; if (($n[1]*10 + $n[0]) < 20) { $t2 .= $ones[($n[1]*10 + $n[0])]; } elsif ($n[0] == 0 && $n[1] != 0) { $t2 .= $tens[$n[1]-1]; } else { $t2 .= $tens[$n[1]-1] . "-" . $ones[$n[0]]; } } return $t2; } sub getFactors { my $x = math::abs($_[0]); my @f; my $j = 0; for (my $i = 1; $i <= ($x/2); $i++) { $f[$j] = $i and $j++ if ($x%$i == 0); } $f[$j]=$x; return @f; }