Zahlen variabel runden

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Zahlen variabel runden

    Guten Tag,

    ich habe da ein kleines Problem.
    Ich bekomme von einer anderen Anwendung Zahlen, diese können zB. so aussehen:

    1132, 11320, 111.355

    Bei der ersten Zahl, möchte ich das sie nur auf den nächsten hunderter gerundet wird, also auf 1200.
    Bei der zweiten Zahl, möchte ich das auf den nächsten 250er Schritt gerundet wird, also 11.500.
    Und bei der letzten Zahl, möchte ich das auf den nächsten tausender gerundet wird, also 112.000.

    Also Zahlen von 1000 - 9999 auf den nächsten hunderter.
    Zahlen von 10.000 - 99.999 auf den nächsten 250er.
    Und Zahlen von 100.000 - x auf den nächsten tausender.

    Es gibt viel zum runden bei Google, das richtige habe ich dort aber leider nicht gefunden - also wie ich mir eigene Rundungsregeln kreieren kann.

    Viele Grüße

    Edit:
    Bitte verschieben, ich denke das ist keine Grundlage, sollte wohl eher in das Hauptforum. Entschuldigung.
    Einfach mit ner if-Abfrage schauen ob die Zahl (z.B. x) die du runden möchtest in einem bestimmten Bereich liegt und dann:

    für x < 10000
    Math.Round(x/100R)*100

    für 100000 <= x
    Math.Round(x/1000R)*1000

    Da Math.Round nur mit Kommazahlen funktioniert, musst du deine Integer zuerst in Kommazahlen umwandeln und dann die Nachkommastellen "wegrunden". Hier noch Infos zu Math.Round(). Das "R" sorgt dafür, dass die 100 bzw. 1000 als Double behandelt werden.

    für 10000 <= x < 100000, wenn du also auf 250er-Schritte runden möchtest, ist das Ganze etwas komplizierter, da Math.Round() keine Option zum Runden auf bestimmte Werte gibt. Du musst dir also was zusammenbasteln, das das für dich tut.

    Soulkick schrieb:

    also wie ich mir eigene Rundungsregeln kreieren kann
    Zum Beispiel so:
    Runden

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    2. Label1.Text = MyRound(1132).ToString
    3. Label2.Text = MyRound(11320).ToString
    4. Label3.Text = MyRound(111355).ToString
    5. End Sub
    6. Private Function MyRound(value As Integer) As Integer
    7. Select Case value
    8. Case 1000 To 9999
    9. value = value \ 100
    10. value += 1
    11. value *= 100
    12. Case 10000 To 99999
    13. value = value \ 250
    14. value += 1
    15. value *= 250
    16. Case Is > 99999
    17. value = value \ 1000
    18. value += 1
    19. value *= 1000
    20. Case Else
    21. ' Werte zu klein
    22. Throw New ArgumentOutOfRangeException(value.ToString & " is out of range")
    23. End Select
    24. Return value
    25. End Function
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    ~blaze~ schrieb:

    gibt bspw. die Zahl der Dezimalstellen für value > 0
    Und dann machst Du Select Case mit 3, 4, 5?
    Was ist daran besser?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    ~blaze~ schrieb:

    Und die erhält man eben über den Logarithmus.
    Ja, das hatte ich auch überlegt.
    Nur will @Soulkick: 100-, 250-, 1000-er Schritte haben, und die sind so per Log nicht realisierbar.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    ~blaze~ schrieb:

    Oder habe ich das missverstanden?
    Ich merke, dass ich Deinen 1. Einwurf missverstanden habe.
    Auch mit Log(x)(Basis y) wirst Du wohl nicht weiterkommen, sagt mir mein Bauchgefühl. :S
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ah, Klammerfehler, hatte erst Math.Abs drinstehen und beim schnellen Ausbessern die falsche Klammer entfernt.

    Moment, mir ist gerade aufgefallen, dass das ja Integer sind ==> Log ist eigentlich nicht allzu toll.
    Kannst du versuchen, die Regeln abstrakt darzustellen? Es ist sehr schwer, sich aus so einer geringen Zahl an Beispielen eine sinnvolle Regel herzuleiten. Für konkrete Dinge ist halt RodFromGermany's Programm ausreichend, aber rein mathematisch gesehen wäre es halt nicht pauschal gültig, entsprechend der ArgumentOutOfRangeException.
    Ich würde auf irgendwas mit 2^(Math.Log10(value)-1) tippen, aber ohne vollständige Definition ist das eher noch nicht so brauchbar. Da es Integer sind, kann man 2^n als 1 << n darstellen, für Math.Log10 habe ich irgendwo mal einen FloorLog2 geschrieben, der analog funktionieren würde. Ist aber nur Optimierung; für hinreichend kleine Longs wäre Double von der Genauigkeit her ausreichend.

    Gruß
    ~blaze~
    Jou. Vielleicht sollte sich @Soulkick: mal dazu äußern.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!