Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
(Deutsche) sprechende Zahlen
emuuu
myCSharp.de - Member

Avatar #avatar-4078.jpg


Dabei seit:
Beiträge: 286

Themenstarter:

(Deutsche) sprechende Zahlen

beantworten | zitieren | melden

Ü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
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von emuuu am .
2+2=5 (für extrem große Werte von 2)
private Nachricht | Beiträge des Benutzers
p!lle
myCSharp.de - Member

Avatar #avatar-3556.jpg


Dabei seit:
Beiträge: 1050

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
emuuu
myCSharp.de - Member

Avatar #avatar-4078.jpg


Dabei seit:
Beiträge: 286

Themenstarter:

beantworten | zitieren | melden

Zitat von p!lle
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)
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15521
Herkunft: BW

beantworten | zitieren | melden

Allgemein gefällt mir der Ansatz von https://github.com/Humanizr/Humanizer mit Fluent Code deutlich besser.
private Nachricht | Beiträge des Benutzers
emuuu
myCSharp.de - Member

Avatar #avatar-4078.jpg


Dabei seit:
Beiträge: 286

Themenstarter:

beantworten | zitieren | melden

Zitat von Abt
Allgemein gefällt mir der Ansatz von https://github.com/Humanizr/Humanizer 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)
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

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.
Zitat
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
private Nachricht | Beiträge des Benutzers