Gesucht: Formel zum Verändern der einzelnen Zahlen einer Ganzzahl

  • Allgemein

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von Artentus.

    Gesucht: Formel zum Verändern der einzelnen Zahlen einer Ganzzahl

    Hi,
    heute einmal ein eher mathematisches bzw. theoretisch-informatisches Gesuch:

    Gibt es, wenn man sich eine Ganzzahl (ganz unmathematisch) als Aneinanderreihung der Ziffern 0-9 vorstellt (z.B. 1234 ---> 1, 2, 3, 4) eine Formel, einzelne Ziffern zu verändern?
    Mithilfe von Potenzen und Modulo ist es ja möglich, einzelne Ziffern auszulesen [Ergebnis = (Zahl / 10^GesuchteZahl-1) % 10].

    Kennt ihr eine solche Formel oder könnt ihr sie mit eurem (bei mir leider offensichlich nicht vorhandenen) mathematischen Genie gar selber aufstellen (so, genug geschleimt ;) ) ?
    Oder würdet ihr die quick-and-very-dirty-Variante empfehlen, einfach in String zu casten, Char zu ändern und zurückzucasten?

    Vielen Dank schon einmal im Voraus!
    Das geht soweit ich weis an einem Computer nur arithmetisch, wenn du die zahl binär betrachtest, also du kannst einzelne Bits austauschen. Für andere Basen musst du immer die String-Darstellung nehmen, denn der Computer versteht nunmal nur binär.
    @-= Christopher =-: So was:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    2. Dim ziffern() = {1, 2, 3, 4, 5, 6}
    3. Dim value As Integer = 0
    4. For Each ziffer In ziffern
    5. value *= 10
    6. value += ziffer
    7. Next
    8. MessageBox.Show(value.ToString)
    9. End Sub
    und das Array ziffern kanst Du belegen wie immer Du willst.
    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!
    Die Darstellung der Zahl in Form eines Arrays (ob jetzt integer-Array oder String aka Char-Array) ist vermutlich doch die Umwandlung wert.
    Schon allein aus Performancegründen einer möglicherweise, falls überhaupt existenten sehr komplexen Formel.

    Danke euch beiden für die Verdeutlichung!
    Für die Umwandlung in ein Array musst du entweder auch erst die String-Darstellung bilden oder dir mit deiner Formel oben umständlich die einzelnen Stellen rauspicken. Ich bin mir nicht sicher, ob es das wirklich wert ist, Stringoperationen sind von Framework gut durchoptimiert.
    @-= Christopher =-:
    Tada... :-D

    VB.NET-Quellcode

    1. Dim zahl As Integer = 12345
    2. Dim stelle As Integer = 3 ' Beginnend von hinten
    3. Dim neu As Integer = 5
    4. Dim resultat As Integer = (zahl - Math.Pow(10, stelle - 1) * (zahl \ CInt(Math.Pow(10, stelle - 1)) Mod 10) + Math.Pow(10, stelle - 1) * neu)


    Input: 12345
    Stelle: 3
    Neue Zahl: 5

    Resultat: 12545

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „EiPott“ ()

    na ich würde ja doch lieber in string umwandeln, und dann substring von anfang bis zu dem zeichen das ersetzt werden soll, dann das neue zeichen zwischenschieben, dann der restliche substring ... anstatt diese menge an mathematischen operationen...
    @-= Christopher =-

    VB.NET-Quellcode

    1. Function ReplaceDigit(ByVal old As Integer, ByVal pos As Integer, ByVal newDigit As Integer) As Integer
    2. Dim c As Integer = 1
    3. ' Potenz berechnen
    4. While pos > 1
    5. c *= 10
    6. pos -= 1
    7. End While
    8. ' Ziffer ersetzen
    9. Return old - (old Mod (c*10)) + newDigit * c + old Mod c
    10. End Function


    Das hier dürfte ohne Konvertierung und Funktionsaufrufen um einiges schneller arbeiten

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Quadsoft“ ()

    Hi
    für b^x könnte man übrigens auch noch eine Optimierung treffen:

    VB.NET-Quellcode

    1. Public Shared Function Power(ByVal base As Integer, ByVal exponent As Integer) As Integer
    2. If exponent <= 0 Then Return (exponent >> 31) + 1
    3. Dim cv As Integer = 1
    4. Do
    5. If (exponent And 1) = 1 Then cv *= base
    6. exponent >>= 1
    7. If exponent = 0 Then
    8. Exit Do
    9. End If
    10. base *= base
    11. Loop
    12. Return cv
    13. End Function
    14. Public Shared Function Power(ByVal base As Long, ByVal exponent As Integer) As Long
    15. If exponent <= 0 Then Return (exponent >> 31) + 1
    16. Dim cv As Long = 1
    17. Do
    18. If (exponent And 1) = 1 Then cv *= base
    19. exponent >>= 1
    20. If exponent = 0 Then
    21. Exit Do
    22. End If
    23. base *= base
    24. Loop
    25. Return cv
    26. End Function


    Gruß
    ~blaze~
    @~blaze~
    Jetzt muss ich aber doch mal fragen, wie kommst du auf If exponent <= 0 Then Return (exponent >> 31) + 1?
    Gut, bei exponent = 0 kommt das richtige (also 1) raus, aber müsste bei kleiner 0 nicht ein Fehler geworfen werden? Bei negativen Exponenten kommt ja ein Bruch raus, und der ist in den wenigsten Fällen ganzzahlig. Außerdem wüsste ich auch nicht, was der Bitshift da überhaupt macht.

    ~blaze~ schrieb:

    Hi
    für b^x könnte man übrigens auch noch eine Optimierung treffen:

    Für den vorliegenden Fall muss man b^x nicht optimieren, da b fest auf 10 gesetzt ist. ich glaube, dass hier die schnelle potenzierungsmethode dann auch keinen nennenswerten geschwindigkeitszuwachs bringt. Natürlich ist es statt in O(pos) in O(log pos) aber ich denke das ist hier unerheblich.