aicher1998
Goto Top

Rechnen mit sehr großen Zahlen (über 100.000 Stellen) mit Komma

Hallo
ich hab da mal ein kleines Provlem.
Ich müsste mit sehr langen Zahlen rechnen (über 100.000 Stellen).
Hab mir deshalb einiges zusammengesucht und um vb.net umgeschrieben.
Allerdings werden keine Komma-Stellen unterstützt.
Mein Code bisher ist folgender:

Module MATHs
    Public Function LTrim0(ByVal strVar As String) As String
        Do Until Len(strVar) = 1 Or Left$(strVar, 1) <> "0"  
            strVar = Mid$(strVar, 2)
        Loop
        LTrim0 = strVar
    End Function

    Public Function Add(ByVal strNo1 As String, ByVal strNo2 As String) As String
        Dim bytSum As Byte
        Dim bytCarry As Byte
        Dim lngMax As Long
        Dim lngVar As Long
        Dim strSum As String = ""  

        strNo1 = LTrim0(strNo1)
        strNo2 = LTrim0(strNo2)
        lngMax = IIf(Len(strNo1) > Len(strNo2), Len(strNo1), Len(strNo2))
        strNo1 = Right$(New String("0", lngMax) & strNo1, lngMax)  
        strNo2 = Right$(New String("0", lngMax) & strNo2, lngMax)  
        For lngVar = Len(strNo1) To 1 Step -1
            bytSum = Val(Mid$(strNo1, lngVar, 1)) + Val(Mid$(strNo2, lngVar, 1)) + bytCarry
            strSum = bytSum Mod 10 & strSum
            bytCarry = bytSum \ 10
        Next lngVar
        If bytCarry Then strSum = bytCarry & strSum

        Return strSum
    End Function

    Public Function Divide(ByVal strNo1 As String, ByVal strNo2 As String) As String
        Dim bytQuo As Byte
        Dim lngVar As Long
        Dim strQuo As String = ""  
        Dim strDiv As String = ""  
        Dim strVar As String = ""  

        strNo1 = LTrim0(strNo1)
        strNo2 = LTrim0(strNo2)
        lngVar = Len(strNo2)
        strDiv = Left$(strNo1, lngVar)
        Do While lngVar <= Len(strNo1)
            strVar = Subtract(strDiv, strNo2)
            bytQuo = 0
            Do While Left$(strVar, 1) <> "-"  
                bytQuo = bytQuo + 1
                strVar = Subtract(strVar, strNo2)
            Loop
            strQuo = strQuo & CStr(bytQuo)
            lngVar = lngVar + 1
            strDiv = Subtract(strNo2, Mid$(strVar, 2)) & Mid$(strNo1, lngVar, 1)
        Loop

        Return LTrim0(strQuo)
    End Function

    Public Function Modulo(ByVal strNo1 As String, ByVal strNo2 As String) As String
        Return Subtract(strNo1, Multiply(strNo2, Divide(strNo1, strNo2)))
    End Function

    Public Function Multiply(ByVal strNo1 As String, ByVal strNo2 As String) As String
        Dim bytPrd As Byte, bytCarry As Byte
        Dim lngVar1 As Long, lngVar2 As Long
        Dim strPrd As String, strVar As String

        strNo1 = LTrim0(strNo1)
        strNo2 = LTrim0(strNo2)

        If Len(strNo1) > Len(strNo2) Then
            strVar = strNo1
            strNo1 = strNo2
            strNo2 = strVar
        End If

        strPrd = "0"  

        For lngVar1 = Len(strNo1) To 1 Step -1
            strVar = New String("0", Len(strNo1) - lngVar1)  
            bytCarry = 0
            For lngVar2 = Len(strNo2) To 1 Step -1
                bytPrd = Mid$(strNo1, lngVar1, 1) * Mid$(strNo2, lngVar2, 1) + bytCarry
                strVar = bytPrd Mod 10 & strVar
                bytCarry = bytPrd \ 10
            Next lngVar2
            If bytCarry Then strVar = bytCarry & strVar
            strPrd = Add(strPrd, strVar)
        Next lngVar1

        Return strPrd
    End Function

    Public Function Subtract(ByVal strNo1 As String, ByVal strNo2 As String) As String
        Dim bytDif As Byte
        Dim bytCarry As Byte
        Dim lngVar As Long
        Dim strDif As String = ""  
        Dim strVar As String = ""  

        strNo1 = LTrim0(strNo1)
        strNo2 = LTrim0(strNo2)
        If Len(strNo1) < Len(strNo2) Or (Len(strNo1) = Len(strNo2) And strNo1 < strNo2) Then
            strVar = strNo1
            strNo1 = strNo2
            strNo2 = strVar
        End If
        strNo2 = Right$(New String("0", Len(strNo1)) & strNo2, Len(strNo1))  
        For lngVar = Len(strNo1) To 1 Step -1
            bytDif = Val(Mid$(strNo1, lngVar, 1)) - Val(Mid$(strNo2, lngVar, 1)) - bytCarry + 10
            strDif = bytDif Mod 10 & strDif
            bytCarry = 1 - bytDif \ 10
        Next lngVar
        strDif = LTrim0(strDif)
        If strVar > "" Then strDif = "-" & strDif  
        Return strDif
    End Function
End Module

Kann mir bitte jemand helfen?
Ich versteh das nämlich nicht so ganz.

Gruß Aicher

Gelöst: ICH DRAF NICHT MIT GLEITKOMMAZAHLEN RECHNEN; SONDERN MIT BYTES

Content-Key: 239548

Url: https://administrator.de/contentid/239548

Printed on: April 18, 2024 at 23:04 o'clock

Member: Xaero1982
Xaero1982 May 29, 2014 at 08:39:48 (UTC)
Goto Top
Moin,

und was genau verstehst du nicht? Warum er keine Kommazahlen berechnet?

Schau dir dann das mal an:
http://de.wikibooks.org/wiki/Visual_Basic_.NET:_Variablen

Vielleicht kommst du selbst drauf...

Gruß
Member: Aicher1998
Aicher1998 May 29, 2014 at 08:56:57 (UTC)
Goto Top
Zitat von @Xaero1982:
und was genau verstehst du nicht? Warum er keine Kommazahlen berechnet?
Klar versteh ich das. Bloß ich versteh nicht ganz, wie ich das machen muss.
Ich hab ja den ganzen Programmcode von einer älteren vb-Sprache auf Vb.net umwandeln müssen.

Danke, aber das kenn ich schon lang face-smile
Und sollte ich bei einem Datentype mal nicht wissen, was deren MinValue und MaxValue sind - ich hab mir da eine kleine Tabelle angefertigt und ausgedruckt.

Gruß Aicher
Member: Xaero1982
Xaero1982 May 29, 2014 at 09:03:02 (UTC)
Goto Top
Du verstehst es ja offenbar nicht warum er keine Kommazahlen anzeigt/berechnet, denn sonst wüsstest du ja wo der Fehler liegt?

Ich muss zugeben, ganz durchgestiegen bin ich nicht bei dem "Code", aber wenn ich mir so die Variablentypen ansehe stelle ich fest:

Byte
Long
String

Mit Byte und Long wirst du dann sicher rechnen...doch weder das eine noch das andere haben Kommastellen, denn es sind Ganzzahlvariablen. Steht ja auch auf der Seite die du schon lange kennst.
Dabei geht es auch nicht um MinValue und MaxValue sondern um Ganzzahlen und Gleitkommazahlen.

Gruß
Member: colinardo
colinardo May 29, 2014 updated at 09:32:43 (UTC)
Goto Top
Moin Aicher,
wie Xaero schon sagt, solltest du mit Gleitkommazahlen wie z.B. Double rechnen:
 Dim wert1 As Double = 1000006636636363666
 Dim wert2 As Double = 1000083838838999999
 Dim ergebnis As Double = wert1 * wert2
 MsgBox(ergebnis)

' = 1,00009047603177E+36  
Grüße Uwe
Member: Aicher1998
Aicher1998 May 29, 2014 at 09:36:58 (UTC)
Goto Top
Zitat von @colinardo:

Moin Aicher,
wie Xaero schon sagt, solltest du mit Gleitkommazahlen wie z.B. Double rechnen:
>  Dim wert1 As Double = 1000006636636363666
>  Dim wert2 As Double = 1000083838838999999
>  Dim ergebnis As Double = wert1 * wert2
>  MsgBox(ergebnis)
> 
> ' = 1,00009047603177E+36  
> 
Blöd bloß, dass Doule kein datentyp ist der 100.000 stellen akzeptiert.
Also nehm ich String

Wie mach ich das dann?
Member: colinardo
colinardo May 29, 2014, updated at Sep 21, 2014 at 13:33:34 (UTC)
Goto Top
Zitat von @Aicher1998:
Blöd bloß, dass Doule kein datentyp ist der 100.000 stellen akzeptiert.
was willst du bitte berechnen, das so viele Stellen hat ?
Also nehm ich String
Wie mach ich das dann?
String wirst du aber trotzdem immer zu einem Format konvertieren müssen mit dem sich rechnen lässt, und da gibt es Grenzen in .NET. Und das mit Nachkomma, da ist dein Rechner sicherlich mehrere Monate beschäftigt face-wink. Eventuell hilft dir das etwas weiter:
bin leider kein Mathematiker.

Grüße Uwe
Member: Aicher1998
Aicher1998 May 29, 2014 at 10:26:01 (UTC)
Goto Top
Zitat von @colinardo:

> Zitat von @Aicher1998:
> Blöd bloß, dass Doule kein datentyp ist der 100.000 stellen akzeptiert.
was willst du bitte berechnen, das so viele Stellen hat ?
Die Antwort hat 2 Stellen: PI
> Also nehm ich String
> Wie mach ich das dann?
String wirst du aber trotzdem immer zu einem Format konvertieren müssen mit dem sich rechnen lässt,
Ja, aber immer nur die einzelnen Stellen werden schrittweise zu einem Val-typ konvertiert.
Ich rechne ja nicht mit der ganzen Zahl sondern lass den Computer rechnen wie ich es rechnen würde (Schule).
Da gibt es doch die Methode der Schnellen Furor Transformation (kurz: FFT), hab aber noch nicht ganz kapiert, wie das funktioniert ...
und da gibt es
Grenzen in .NET. Und das mit Nachkomma, da ist dein Rechner sicherlich mehrere Monate beschäftigt face-wink.
Eher Stunden face-smile

Eventuell hilft dir
Werd ich schauen
bin leider kein Mathematiker.
Ich hab ne Eins in Mathe face-smile
Gruß Chris
Member: colinardo
colinardo May 29, 2014 updated at 10:30:51 (UTC)
Goto Top
Zitat von @Aicher1998:
Ich hab ne Eins in Mathe face-smile
dann sollte das für dich ja kein Problem sein, das rauszufinden
Member: Aicher1998
Aicher1998 May 29, 2014 at 10:37:45 (UTC)
Goto Top
Ja das bringt vielleicht was.
Auf diesen Datentype bin ich vor längerer Zeit schonmal gestoßen,
wusste aber nicht, wie ich hier die Zahl (bzw. den String) in die Byzrs umwandeln soll,
den mit dem System.Text.ASCIIEncoding.GetBytes oder so ähnlich hat es zwar erstmals funktioniert, aber bei längeren Zahlen wurde ein Problem daraus, da die Zhalen minimal mit dem zu erwartendem Ergebnis abwichen.
Da auf der Seite ja jetzt zu sehen ist, dass es evtl. mit Parse funktioniert, kann ich es ja nochmal probieren, sobald ich VB wieder offen hab. DANKE
Member: Aicher1998
Aicher1998 May 29, 2014 at 10:39:35 (UTC)
Goto Top
Zitat von @colinardo:

> Zitat von @Aicher1998:
> Ich hab ne Eins in Mathe face-smile
dann sollte das für dich ja kein Problem sein, das rauszufinden
Ja aber keine Eins im Programmieren.
Ich kenne unzählige Mathematischen Tricks wie man beliebige Zahlen im Kopf zusammenrechnen oder wie man die Wurzel einer Zahl im Kopf ausrechnet (oder Annäherungsverfahren!)
Member: Aicher1998
Aicher1998 May 29, 2014 at 10:43:27 (UTC)
Goto Top
Der unterstützt auch nur Ganzzahlen und ist somit - mal abgesehen davon dass dieser Type im Gegensatz zu meinem Code sogar Operatoren hat, die ich aber noch einbauen werd - auch nicht besser wie mein Code
aber trotzdem Danke
Member: bastla
bastla May 29, 2014 at 13:44:45 (UTC)
Goto Top
Hallo Aicher1998!

Nun bin ich auch kein Mathematiker, aber ich könnte mir vorstellen, dass sich doch vorweg die Größenordnung (10er-Potenz) des Ergebnisses sollte bestimmen lassen - und dann würde ja das Komma während der Berechnung überhaupt nicht benötigt ...

Grüße
bastla