Skip to content

Instantly share code, notes, and snippets.

@davestevens
Created December 6, 2012 20:26
Show Gist options
  • Save davestevens/4228028 to your computer and use it in GitHub Desktop.
Save davestevens/4228028 to your computer and use it in GitHub Desktop.
Convert decimal numbers to string and vice versa
#!/usr/bin/perl
use strict;
# Kind of useless script to convert numbers to their word equivalent and back
# Call dec_to_str() with a decimal value, returns a string containing the word equivalent
# eg. dec_to_str(123456) := one hundred and twenty three thousand four hundred and fifty six
# Call str_to_dec() with a number in words, returns decimal value
# eg. str_to_dec("five million and twenty three") := 5000023
# number names
# less than twenty
my @ltt = ('', 'one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen');
# twenty to ninety
my @ttn = ('twenty','thirty','forty','fifty','sixty','seventy','eighty','ninety');
# powers of ten
my @pot = ('','thousand','million','billion','trillion','quadrillion', 'quintillion');
##### TEST
for(my $i=0;$i<100;++$i) {
my $r = int(rand(0xFFFFFFFFFFFF));
print 'input: ' . $r . "\n";
my $d2s = dec_to_str($r);
print "\t" . 'dec_to_str: ' . $d2s . "\n";
my $s2d = str_to_dec($d2s);
print "\t" . 'str_to_dec: ' . $s2d . "\n";
if($s2d != $r) {
print 'Error, mismatch' . "\n";
exit -1;
}
}
##### /TEST
exit;
sub dec_to_str
{
my $d = shift(@_);
my @n;
while($d > 0.9) {
push(@n, {'d', [split(//, sprintf("%03d", ($d % 1000)))], 's', ''});
$d /= 1000;
}
foreach my $t (@n) {
if($t->{'d'}[0] != 0) {
$t->{'s'} .= $ltt[$t->{'d'}[0]] . ' hundred';
}
if(defined($ltt[$t->{'d'}[1] . $t->{'d'}[2]])) {
if(($t->{'s'}) && ($ltt[($t->{'d'}[1] . $t->{'d'}[2])])){
$t->{'s'} .= ' and ';
}
$t->{'s'} .= $ltt[($t->{'d'}[1] . $t->{'d'}[2])];
}
else {
if($t->{'s'}) {
$t->{'s'} .= ' and ';
}
$t->{'s'} .= $ttn[$t->{'d'}[1] - 2];
if($t->{'d'}[2]) {
$t->{'s'} .= ' ' . $ltt[$t->{'d'}[2]];
}
}
}
my $str = '';
for(my $i=$#n;$i>=0;--$i) {
if($n[$i]->{'s'}) {
if($str) {
$str .= ' ';
}
$str .= $n[$i]->{'s'};
if(($pot[$i]) && ($i)) {
$str .= ' ' . $pot[$i];
}
}
}
return $str ? $str : 'zero';
}
sub str_to_dec
{
my @str = split(/\s+,?\s*/, shift(@_));
my $d = 0;
my $total = 0;
for(my $i=0;$i<@str;++$i) {
if((my $tmp = in_array($str[$i], \@ltt)) != -1) {
$d += $tmp;
}
elsif((my $tmp = in_array($str[$i], \@ttn)) != -1) {
$d += (($tmp+2) * 10);
}
elsif($str[$i] eq 'hundred') {
$d *= 100;
}
elsif((my $tmp = in_array($str[$i], \@pot)) != -1) {
$total += $d * (10 ** ($tmp * 3));
$d = 0;
}
}
return $total + $d;
}
sub in_array
{
my $s = shift(@_);
my $a = shift(@_);
for(my $idx=0;$idx<@{$a};++$idx) {
if(${$a}[$idx] eq $s) {
return $idx;
}
}
return -1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment