www

ein Webangebot von rotering-net.de

PHP-Skript: Zahl in Zahlwort umwandeln

Mittels der hier vorgestellten Funktion kann eine beliebige Ganzzahl (positiv oder negativ) in ein Zahlwort deutscher Sprache umgewandelt werden.

Anwendungsbeispiel

Die Anwendung ist denkbar einfach. Wir übergeben der Funktion schlicht die Zahl, die wir in ein Zahlwort umwandeln möchten und bekommen das Zahlwort zurückgeliefert.

<p> Die Zahl 13947 lautet ausgeschrieben:<br /> <?php echo num2text(13947); ?> </p>

Stellen Sie vor dem Aufruf der Funktion unbedingt sicher, dass die übergebene Zahl auch eine Ganzzahl ist. Andernfalls könnte die Funktion in eine Endlosschleife geraten. Außerdem kann PHP Ganzzahlen nur bis zu einem bestimmten Wert, der von der eingesetzten Prozessorarchitektur abhängt, korrekt verarbeiten. Die Systemkonstante PHP_INT_MAX liefert die größtmögliche Ganzzahl zurück.

Hier einmal zum Ausprobieren in einem Formular für beliebige, ganze Zahlen:

:

Syntax

string num2text ($pNumber)

$pNumber
Die Ganzzahl, die in ein Zahlwort umgewandelt werden soll.

Kommentiertes Skript

Wir beginnen damit einige Konstanten und Arrays zu deklarieren, die sämtliche Zahlwörter und sonstige Wortbestandteile enthalten, die wir später in der Funktion benötigen. So bleibt die Funktion übersichtlich und bei Bedarf kann man die Schreibweise der Zahlwörter hier einfach anpassen.

define('NUMERAL_SIGN', 'minus'); define('NUMERAL_HUNDREDS_SUFFIX', 'hundert'); define('NUMERAL_INFIX', 'und'); $lNumeral = array('null', 'ein', 'zwei', 'drei', 'vier', 'fünf', 'sechs', 'sieben', 'acht', 'neun', 'zehn', 'elf', 'zwölf', 'dreizehn', 'vierzehn', 'fünfzehn', 'sechzehn', 'siebzehn', 'achtzehn', 'neunzehn'); $lTenner = array('', '', 'zwanzig', 'dreißig', 'vierzig', 'fünfzig', 'sechzig', 'siebzig', 'achtzig', 'neunzig'); $lGroupSuffix = array(array('s', ''), array('tausend ', 'tausend '), array('e Million ', ' Millionen '), array('e Milliarde ', ' Milliarden '), array('e Billion ', ' Billionen '), array('e Billiarde ', ' Billiarden '), array('e Trillion ', ' Trillionen '));

Die eigentliche Funktion num2text() leistet erstaunlich wenig. Ist die mit dem Parameter $pNumber übergebene Zahl gleich 0, so können wir unmittelbar das Zahlwort „null“ zurückgeben und sind fertig. Ist die Zahl negativ, so setzen wir das Wort „minus“ vor die Zahl und wandeln die Zahl mittels der abs()-Funktion in eine positive Zahl um. Bei allen Zahlen ungleich 0 rufen wir dann die Funktion num2text_group() auf, welche mittels einer Rekursion die Umwandlung einer positiven Zahl in ein Zahlwort vornimmt.

function num2text($pNumber) { global $lNumeral; if ($pNumber == 0) { return $lNumeral[0]; // „null“ } elseif ($pNumber < 0) { return NUMERAL_SIGN . ' ' . num2text_group(abs($pNumber)); } else { return num2text_group($pNumber); } }

Für die rekursive Funktion num2text_group() müssen wir uns nun darüber Gedanken machen, wie ein Zahlwort im Deutschen aufgebaut ist. Neben allen Unregelmäßigkeiten finden wir doch einige grundlegende Regeln. So wie wir eine Zahl mit Punkten oder Abständen in Dreiergruppen unterteilen, so wird auch beim Zahlwort jede Dreiergruppe separat gesprochen und mit einem Suffix versehen, welches angibt, um welche Dreiergruppe es sich handelt: einhundertfünfzehn-Millionen | siebenhundertfünfundvierzig-tausend | zweihundertdreizehn. Unsere Rekursion wird daher von hinten jede Dreiergruppe durchlaufen und getrennt bearbeiten. Damit wir wissen, in welcher Dreiergruppe wir uns gerade befinden, wird die Variable $pGroupLevel bei jedem Durchlauf eins hochgezählt.

Wir beginnen unsere Funktion damit, dass wir prüfen, ob die mit dem Parameter $pNumber übergebene Zahl gleich 0 ist. Da wir nach jeder Abarbeitung einer Dreiergruppe diese Dreiergruppe aus der Zahl entfernen, ist die komplette Zahl abgearbeitet, wenn wir 0 erreicht haben. Dadurch haben wir eine geeignete Abbruchbedingung für unsere Rekursion. Sind dagegen noch Stellen abzuarbeiten, extrahieren wir die letzten drei Ziffern aus der Zahl, was wir mit einer Modulo-1000-Rechnung erreichen.

if ($pNumber == 0) { return ''; } $lGroupNumber = $pNumber % 1000;

Nun gibt es drei Fälle. Fall 1: Die komplette Dreiergruppe enthält nur Nullen, ist also gleich 0. In diesem Fall brauchen wir in diesem Schritt gar nichts tun, da diese Dreiergruppe überhaupt nicht gesprochen wird. Fall 2: Die Dreiergruppe ist genau 1. Diesen Fall müssen wir getrennt betrachten, da unter Umständen die grammatikalische Form von Zahlwort und Suffix angepasst werden muss. Daher gibt es auch in den anfänglichen Defintionen der Gruppen-Suffixe eine getrennte Angabe für Singular und Plural. Es heißt beispielsweise „eintausend“ oder „zweitausend“, aber „eine Million“ oder „zwei Millionen“. Fall 3 umfasst dann alle Zahlen größer 1, die sich nun regelmäßig ergeben.

if ($lGroupNumber == 1) { $lResult = $lNumeral[1] . $lGroupSuffix[$pGroupLevel][0]; // „eine Milliarde“ } elseif ($lGroupNumber > 1) { $lResult = '';

Die Sprechabfolge der Ziffern jeder Dreiergruppe ist im Deutschen nun: 1. Ziffer, 3. Ziffer, 2. Ziffer. Die erste Ziffer erhalten wir mittels Division der Gruppenzahl $lGroupNumber durch 100 und anschließendem Abrunden mittels floor(). Wir wählen das entsprechende Zahlwort für die erste Ziffer und hängen das Suffix „hundert“ an.

$lFirstDigit = floor($lGroupNumber / 100); if ($lFirstDigit > 0) { $lResult .= $lNumeral[$lFirstDigit] . NUMERAL_HUNDREDS_SUFFIX; // „fünfhundert“ }

Bei der 2. und 3. Ziffer gibt es nun wiederum diverse Sonderfälle zu betrachten. Daher bestimmen wir neben den einzelnen Ziffern auch die zusammengesetzte Zahl beider Ziffern ($lLastDigits), mit der wir eine Fallunterscheidung durchführen.

$lLastDigits = $lGroupNumber % 100; $lSecondDigit = floor($lLastDigits / 10); $lThirdDigit = $lLastDigits % 10;

Fall 1: Die zusammengesetzte Zahl $lLastDigits ist gleich 0. Hier müssen wir wieder nichts ausgeben. Fall 2: Die Zahl ist gleich 1. In diesem Fall muss nur die grammatikalische Form durch Anhängen eines „s“ angepasst werden. Fall 3: Die Zahl ist größer als 1, aber kleiner als 19. In diesem Zahlbereich gibt es so viele Unregelmäßigkeiten, dass wir bereits anfangs alle Ziffernpaare vordefiniert haben. Fall 4: Bei allen übrigen Zahlen wird zunächst die 3. Ziffer ausgegeben, sofern diese vorhanden ist, und ein „und“-Infix angefügt. Anschließend wird die Zehnerstelle wegen erneuter Unregelmäßigkeiten aus einer separaten Definitionstabelle abgelesen.

if ($lLastDigits == 1) { $lResult .= $lNumeral[1] . 's'; // „eins“ } elseif ($lLastDigits > 1 && $lLastDigits < 20) { $lResult .= $lNumeral[$lLastDigits]; // "dreizehn" } elseif ($lLastDigits >= 20) { if ($lThirdDigit > 0) { $lResult .= $lNumeral[$lThirdDigit] . NUMERAL_INFIX; // „sechsund…“ } $lResult .= $lTenner[$lSecondDigit]; // „…achtzig“ }

Abschließend hängen wir das reguläre Dreiergruppen-Suffix an. Den Rest erledigt die Rekursion. Das Zahlwort setzt sich demgemäß zusammen aus dem Zahlwort der noch verbleibenen Ziffern und dem Zahlwort, welches wir gerade bestimmt haben. Beim rekursiven Aufruf, mit dem wir das Zahlwort der verbleibenen Ziffern bestimmen, müssen wir unsere Zahl durch 1000 Dividieren und Abrunden, da wir ja die letzten drei Ziffern abgearbeitet haben, und das Gruppenlevel um 1 erhöhen, damit der nächste Durchlauf wieder das korrekte Dreiergruppen-Suffix auswählt.

$lResult .= $lGroupSuffix[$pGroupLevel][1]; // „Millionen“ } return num2text_group(floor($pNumber / 1000), $pGroupLevel + 1) . $lResult;

Skript zum Herunterladen

Das Skript ist in einer Textdatei mit der Kodierung UTF-8 hinterlegt, damit es nicht vom PHP-Interpreter auf meinem Webspace ausgeführt wird und Sie es herunterladen können. Sie können den benötigten Programmcode entweder in Ihr Skript hinüberkopieren oder aber das Skript speichern und die Endung auf .php ändern.

zahl-in-zahlwort-umwandeln.txt

Andere Projekte, die dieses Skript verwenden (Auswahl)