myCSharp.de - DIE C# und .NET Community (https://www.mycsharp.de/wbb2/index.php)
- Gemeinschaft (https://www.mycsharp.de/wbb2/board.php?boardid=64)
-- .NET-Komponenten und C#-Snippets (https://www.mycsharp.de/wbb2/board.php?boardid=67)
--- (Deutsche) sprechende Zahlen (https://www.mycsharp.de/wbb2/thread.php?threadid=119496)


Geschrieben von emuuu am 27.07.2017 um 22:19:
  (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.

C#-Code:
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


Geschrieben von p!lle am 28.07.2017 um 12:54:
 
Ganz nice, ein paar Punkte lassen sich allerdings noch optimieren:


Geschrieben von emuuu am 01.08.2017 um 12:46:
 
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) ".


Geschrieben von Abt am 01.08.2017 um 12:52:
 
Allgemein gefällt mir der Ansatz von  https://github.com/Humanizr/Humanizer mit Fluent Code deutlich besser.


Geschrieben von emuuu am 01.08.2017 um 13:08:
 
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.


Geschrieben von herbivore am 05.08.2017 um 06:37:
 
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


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 26.05.2020 20:32