Cheatah: Mein Ansatz

Beitrag lesen

Hi allerseits,

das konnte ich ja nicht auf mir sitzen lassen, daß ich eine Methode vorgebe und dann jemand anders die Lösung postet *g* :-)))

Also, hier ist nun mein Ansatz. Die Null wird nicht abgefragt, für "ein Tausend" und "eine Million/Billion/etc." habe ich einen provisorischen Quickhack gemacht (ist sonst "eins Tausend/Million/Billion/etc."), sonst dürfte alles beachtet worden sein, denke ich. Man kann die Zahlen nach deutscher und englischer Regel ausgeben ("zweiundvierzig" oder "vierzigundzwei"). Amerikanische Zählweise (million*1000 = billion statt milliard) ist nicht möglich, dazu müßte ich einen unmathematischen Ansatz wählen *g*, dafür sind auch die Variablen an sich kürzer (und weniger, weil ich den Plural nicht für jedes Wort einzeln definieren muß). Naja, ich höre mal auf und poste den Quellcode:

--- cut here to damage your monitor ---
#!/usr/bin/perl

Parameter auslesen:

$par = $ENV{'QUERY_STRING'};

Definition notwendiger Variablen:

@bname = ('', 'Mill', 'Bill', 'Trill', 'Quadrill', 'Quintill', 'Sextill', 'Septill', 'Oktill', 'Nonill', 'Dezill');
@hname = ('null', 'ein', 'zwei', 'drei', 'vier', 'fünf', 'sechs', 'sieben', 'acht', 'neun');
@dname = ('', 'zehn', 'zwanzig', 'dreißig', 'vierzig', 'fünfzig', 'sechzig', 'siebzig', 'achtzig', 'neunzig');
@d2name = ('zehn', 'elf', 'zwölf', 'dreizehn', 'vierzehn', 'fünfzehn', 'sechzehn', 'siebzehn', 'achtzehn', 'neunzehn');
@ename = ('null', 'eins', 'zwei', 'drei', 'vier', 'fünf', 'sechs', 'sieben', 'acht', 'neun');
$million = 'ion';  $millions = 'ionen';
$milliard = 'iarde'; $milliards = 'iarden';
$thousand = 'Tausend';
$hundred = 'hundert';
$and = 'und';  # '' in english, 'und' in german
$lang = 1;  # 0 = 'fifty one', 1 = 'one fifty' (german)
$komma = 'Komma';
$minus = 'Minus';

Ausgabe des Wertes:

print "Content-type: text/html\n\n";
print "$par = " . &num2word($par) . "<BR>\n";
exit;

Hier folgen die eigentlichen Funktionen:

sub num2word {
   my $num = $_[0];
   my $string = ($num =~ /-/) ? $minus . ' ' : '';
   if ($num =~ /^(.*),(.*)$/) { $num = $1; $real = $2; }
   $num =~ s/\D//g;
   $real =~ s/\D//g;
  
   $string .= &num2string($num,0);
   # Folgende zwei Zeilen sind eine Notlösung, die den Text nur schöner machen:
      $string =~ s/eins (\S*?)illi/eine $1illi/g;
      $string =~ s/eins $thousand/ein $thousand/;
      # ('ein Tausend' oder 'eine Million' sehen besser aus als 'eins Tausend' und 'eins Million')
   if ($real) {
      $string .= ' ' . $komma . ' ';
      foreach (split(//,$real)) { $string .= $ename[$_] . ' '; }
   }
   return $string;
}

sub num2string {
   my $this = $_[0];
   my $temp;
   if ($this =~ /^(.*)(.{6})/) { $still = $1; $temp = $2; } else { $still = 0; $temp = $this; }
   if ($temp =~ /(.*)(.{3})/) { $high = $1; $low = $2; } else { $high = 0; $low = $temp; }
   $temp = &hundreds($high,$_[1],1) . &hundreds($low,$_[1],0);
   if ($still > 0) { return &num2string($still, $_[1]+1) . $temp; }
   else { return $temp; }
}

sub hundreds {
   my $val = $_[0];
   my $oldval = $val;
   my $block = $_[1];
   my $type = $_[2];
   my $temp = '';
   my $temp2 = '';
   my $temp3 = '';
   if ($val >= 100) { $temp = $hname[int($val/100)] . $hundred; $val = $val % 100; }
   if ($val >= 20) { $temp2 = $dname[int($val/10)]; $val = $val % 10; }
   elsif ($val >= 10) { $temp2 = $d2name[$val-10]; $val = 0; }
   if ($val > 0) { $temp3 = $ename[$val]; }
   if ($lang == 0) {
      if ($temp3) {
         if ($temp.$temp2) { $temp = $temp . $temp2 . $and . $temp3; }
         else { $temp = $temp3; }
      }
      else { $temp = $temp . $temp2; }
   } else {
      if ($temp2) {
         if ($temp.$temp3) { $temp = $temp . $temp3 . $and . $temp2; }
         else { $temp = $temp2; }
      }
      else { $temp = $temp . $temp3; }
   }
   if ($temp) {
      $temp .= ' ' . $bname[$block];
      if ($type == 1) {
         if ($block > 0) { if ($oldval > 1) { $temp .= $milliards; } else { $temp .= $milliard; } }
         else { $temp .= $thousand; }
      } else {
         if ($block > 0) { if ($oldval > 1) { $temp .= $millions; } else { $temp .= $million; } }
      }
      $temp .= ' ';
   }
   return $temp;
}
--- cut here to damage your monitor ---

Die letzte Funktion ist ziemlich lang, dafür sind mir aber auch keine "undeutschen" Wörter mehr aufgefallen :-) Wenn jemand was findet, bitte bescheid sagen!

Ach ja, Nachkommazahlen bitte mit "," abtrennen, nicht mit "." ;-)

Cheatah