Laden...

(Deutsche) sprechende Zahlen

Erstellt von emuuu vor 6 Jahren Letzter Beitrag vor 6 Jahren 9.533 Views
emuuu Themenstarter:in
286 Beiträge seit 2011
vor 6 Jahren
(Deutsche) sprechende Zahlen

Übersetzung von Integer in sprechende Zahlen

Habe mal aus Langeweile einen Codesnippet aus einer alten Vorlesung in C# übersetzt.
Dieses kann Integerwerte in ausgeschriebene Zahlen, bis 10^27, (Einhundertfünfundfünfzig) übersetzen.


public static class SprechendeZahlen
    {
        private static string[] kleiner20 = new string[] { "null", "ein", "zwei", "drei", "vier", "fünf", "sechs", "sieben", "acht", "neun", "zehn", "elf", "zwölf", "dreizehn", "vierzhen", "fünfzehn", "sechszehn", "siebzehn", "achtzehn", "neunzehn" };
        private static string[] zehner = new string[] { "null", "zehn", "zwanzig", "dreißig", "vierzig", "fünfzig", "sechzig", "siebzig", "achtzig", "neunzig" };
        private static string[] singular = new string[] { "s", "tausend", "e Million", "e Milliarde", "e Billion", "e Billiarde", "e Trillion", "e Trilliade" };
        private static string[] plural = new string[] { "", "tausend", "Millionen", "Milliarden", "Billionen", "Billiarden", "Trillionen", "Trilliaden", "Quadrillionen", "Quadrilliarden" };

        public static string GetZahlenname(int zahl)
        {
            if (zahl == 0)
                return "Null";
            else if (zahl < 1 || zahl >=  Math.Pow(plural.Length, 28))
                return "InvalidNumber";
            List<int> gruppe = new List<int>();
            int i = -1, stellen;
            while (zahl>0)
            {
                stellen = zahl % 1000;
                zahl = zahl / 1000;
                i++;
                gruppe.Add(stellen);
            }

            StringBuilder sb = new StringBuilder();
            while (i>=0)
            {
                sb.Append(GetHunderter(gruppe[i], singular[i], plural[i]));
                i--;
            }
            return sb.ToString();
        }

        private static string GetHunderter(int zahl, string singular, string plural)
        {
            if (zahl == 0)
                return "";
            else if (zahl == 1)
                return "ein" + singular;
            StringBuilder sb = new StringBuilder();

            var h = zahl / 100;
            var r = zahl % 100;
            if (h > 0)
                sb.Append(kleiner20[h] + "hundert");
            if (r>0)
            {
                if (r == 1)
                    sb.Append("eins");
                else if (r < 20)
                    sb.Append(kleiner20[r]);
                else
                {
                    var z = r / 10;
                    var rr = r % 10;
                    if (rr > 0)
                        sb.Append(kleiner20[rr]);
                    if (rr > 0 && z > 0)
                        sb.Append("und");
                    if (z > 0)
                        sb.Append(zehner[z]);
                }
            }
            return sb.ToString()+plural;
        }
    }

Hier im Forum und sonstigem Netz gibts dazu zahlreiche Lösungen, finde obige aber eleganter/übersichtlicher und vor allem im Bereich sämtlicher im Alltag ausgeschriebener Zahlen

MfG
emuuu

Sprechende Zahlen

2+2=5( (für extrem große Werte von 2)

1.040 Beiträge seit 2007
vor 6 Jahren

Ganz nice, ein paar Punkte lassen sich allerdings noch optimieren:*0 wird nicht unterstützt *negative Zahlen werden nicht unterstützt -> uint nutzen? *"Billionen", "Billiarden", "Trillionen", "Trilliaden", "Quadrillionen", "Quadrilliarden" kann aus dem plural-Array raus

emuuu Themenstarter:in
286 Beiträge seit 2011
vor 6 Jahren

Ganz nice, ein paar Punkte lassen sich allerdings noch optimieren:
0 wird nicht unterstützt

negative Zahlen werden nicht unterstützt -> uint nutzen?

"Billionen", "Billiarden", "Trillionen", "Trilliaden", "Quadrillionen", "Quadrilliarden" kann aus dem plural-Array raus

Edit 1: Unterstützung von 0 hinzugefügt.
To Go:
uint ist zwar gut, allerdings muss man dann jedes mal aus einem int-Value ein uint machen, was ich blöd finde, da man meistens mit int arbeitet und somit in den meisten fällen casten muss. Und ich caste lieber in der Ausnahme als in der Regel.

Unabhängig vom MaxValue von int will ich das ganze für double umsetzen.
Sprich der Wert wird in ganze Zahlen und Nachkommastellen aufgeteilt. Muss nur schauen wie ich das umsetze:
Da eigentlich nur buchhalterische Zahlen ausgeschrieben werden würde ich dem ganzen ein Math.Round(x, 2) vorschalten und die Nachkommastelle auch als ganze Zahl übersetzen (nicht wissenschaftliche Aussprache).
Laut Duden wäre die korrekte Notation dafür " (KOMMA) ".

2+2=5( (für extrem große Werte von 2)

16.806 Beiträge seit 2008
vor 6 Jahren

Allgemein gefällt mir der Ansatz von https://github.com/Humanizr/Humanizer mit Fluent Code deutlich besser.

emuuu Themenstarter:in
286 Beiträge seit 2011
vor 6 Jahren

Allgemein gefällt mir der Ansatz von
>
mit Fluent Code deutlich besser.

GermanNumberToWordsConverter

Finde ich den von von mir geposteten Ansatz wesentlich eleganter weil der, theoretisch viel besser nach oben skaliert (neue Dimension =>stringarray erweitern)

Mir ging es mit dem Post vor allem um die Effizienz der Umsetzung.

2+2=5( (für extrem große Werte von 2)

49.485 Beiträge seit 2005
vor 6 Jahren

Hallo emuuu,

die Unterstützung für negative Zahlen wäre doch ganz einfach zu realisieren. Falls die Zahl negativ ist, könnte man "Minus " + GetZahlenname (-zahl) zurückgeben. Nur für int.MinValue müsste man noch eine Sonderbehandlung einbauen, weil -int.MinValue außerhalb des Wertebereichs eins int liegt (es würde jedoch innerhalb des Wertebereichs eines longs und erst recht Decimals liegen).

Generell könntest du überlegen, ob du den Wertebereich nicht gleich auf long und/oder sogar Decimal ausweitest. Das löst zwar das MinValue Problem nicht, aber zumindest die Erweiterung auf long kostet sehr wenig und behebt eine unnötige Einschränkung.

würde ich dem ganzen ein Math.Round(x, 2) vorschalten und die Nachkommastelle auch als ganze Zahl übersetzen (nicht wissenschaftliche Aussprache).

Ich würde den Benutzer bestimmen lassen, wie viele Nachkommastellen er ausgegeben haben will und auch wie er die Nachkommastellen ausgegeben haben will, also als Zahl oder Ziffernfolge.

herbivore