Fakultät Rechner

  • Hallo,

    da ich irgendwie nirgendwo einen Fakultätsrecher gefunden habe der mit AutoIt geschrieben ist, habe ich mir mal überlegt einen eigenen zu schreiben. Der hier rechnet jede Fakultät aus, bei sehr großen Zahlen benötigt er allerdings extrem lange:

    Spoiler anzeigen
    [autoit]

    #include <String.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $Zahl = InputBox('Fakultäts rechner', 'Gebe bitte eine Zahl ein von der die Fakultät berechnet werden soll:')
    $Time = TimerInit()
    MsgBox(0, '', _Fakultaet($Zahl) & @CRLF & @CRLF & 'Es wurden ' & TimerDiff($Time)/1000 & ' Sekunden benötigt!')

    [/autoit] [autoit][/autoit] [autoit]

    #region Functions

    [/autoit] [autoit][/autoit] [autoit]

    Func _Fakultaet($iNumber)
    Local $sBetween = 1
    For $iZahl = 1 To $iNumber Step 1
    ConsoleWrite($iZahl & @CRLF)
    $sBetween = _Mul($iZahl, $sBetween)
    Next
    Return $sBetween
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Zero($Number)
    Local $sResultNumber = ''
    For $i = 1 To $Number
    $sResultNumber &= '0'
    Next
    Return $sResultNumber
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Mul($sStringNum_1, $sStringNum_2)

    [/autoit] [autoit][/autoit] [autoit]

    Local $Array[StringLen($sStringNum_1) + 1]

    [/autoit] [autoit][/autoit] [autoit]

    $sStringNum_1 = String($sStringNum_1)
    $sStringNum_2 = String($sStringNum_2)

    [/autoit] [autoit][/autoit] [autoit]

    Local $sSplit_1, $sSplit_2
    Local $sResult

    [/autoit] [autoit][/autoit] [autoit]

    $sSplit_1 = StringSplit($sStringNum_1, '')
    $sSplit_2 = StringSplit($sStringNum_2, '')

    [/autoit] [autoit][/autoit] [autoit]

    Local $sBetweenResult, $sBetweenResult2, $sBetween

    [/autoit] [autoit][/autoit] [autoit]

    For $i_1 = 1 To $sSplit_1[0] Step 1
    For $i_2 = $sSplit_2[0] To 1 Step -1
    $sBetweenResult = $sSplit_1[$i_1] * $sSplit_2[$i_2] + $sBetween
    $sBetween = ''
    If $sBetweenResult >= 10 Then
    $sBetween = StringTrimRight(String($sBetweenResult), 1)
    $sBetweenResult = StringTrimLeft($sBetweenResult, StringLen($sBetweenResult) - 1)
    EndIf
    $sBetweenResult2 = $sBetweenResult & $sBetweenResult2
    Next
    $Array[$i_1] = $sBetween & $sBetweenResult2 & _Zero($sSplit_1[0] - $i_1)

    [/autoit] [autoit][/autoit] [autoit]

    $sBetweenResult2 = ''
    $sBetween = ''
    Next

    [/autoit] [autoit][/autoit] [autoit]

    $sBetween = 0

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To UBound($Array) - 1
    $sBetweenOld = $sBetween
    $sBetween = _Add($sBetween, $Array[$i])
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $sBetween

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Add($sStringNum_1, $sStringNum_2)

    [/autoit] [autoit][/autoit] [autoit]

    $sStringNum_1 = String($sStringNum_1)
    $sStringNum_2 = String($sStringNum_2)

    [/autoit] [autoit][/autoit] [autoit]

    Local $Len_1 = StringLen($sStringNum_1)
    Local $Len_2 = StringLen($sStringNum_2)

    [/autoit] [autoit][/autoit] [autoit]

    If $Len_2 > $Len_1 Then $sStringNum_1 = _Zero($Len_2 - $Len_1) & $sStringNum_1
    If $Len_1 > $Len_2 Then $sStringNum_2 = _Zero($Len_1 - $Len_2) & $sStringNum_2

    [/autoit] [autoit][/autoit] [autoit]

    Local $sSplit_1, $sSplit_2
    Local $sResult

    [/autoit] [autoit][/autoit] [autoit]

    $sSplit_1 = StringSplit($sStringNum_1, '')
    $sSplit_2 = StringSplit($sStringNum_2, '')

    [/autoit] [autoit][/autoit] [autoit]

    Local $sBetweenResult = 0, $sBetween = 0

    [/autoit] [autoit][/autoit] [autoit]

    For $i = $sSplit_1[0] To 1 Step -1
    $sBetweenResult = Number($sSplit_1[$i]) + Number($sSplit_2[$i]) + Number($sBetween)
    $sBetween = 0
    If $sBetweenResult >= 10 Then
    $sBetween = StringTrimRight(String($sBetweenResult), 1)
    $sBetweenResult = StringTrimLeft($sBetweenResult, StringLen($sBetweenResult) - 1)
    EndIf
    $sResult &= $sBetweenResult
    Next

    [/autoit] [autoit][/autoit] [autoit]

    If $sBetween <> 0 Then
    $sResult = $sBetween & _StringReverse($sResult)
    Else
    $sResult = _StringReverse($sResult)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return $sResult
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    #endregion Functions

    [/autoit]
  • Hallo.
    Warum machst du es so kompliziert ?

    Spoiler anzeigen
    [autoit]

    ConsoleWrite("Die Fakultät von 5 ist " & _Faku(5) & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    Func _Faku($iNum)
    For $i = $iNum - 1 To 1 Step -1
    $iNum *= $i
    Next
    Return $iNum
    EndFunc

    [/autoit]


    So ist es viel einfacher!
    MfG. PrideRage

    Meine Projekte:
    ClipBoard Manager (beendet)
    Gutes ClipBoard Verwaltungs Programm mit nützlichen Funktionen.

    HTML Creator (beendet)
    Nützliches Tool um schnell ein eigenes HTML Dokument zu erstellen.

  • Für "große" Fakultäten gibts doch die BIGINT.UDF...
    Für den "Integer" Bereich gibts ein schnelles Beispiel im ASM-Thread.

    Spoiler anzeigen
    [autoit]

    ;Fakultät im Integerbereich 0-12

    [/autoit] [autoit][/autoit] [autoit]

    $fac=_asmFakultaet(3)
    MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$fac' & @lf & @lf & 'Return:' & @lf & $fac) ;### Debug MSGBOX

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    func _asmFakultaet($int)
    ;http://www.autoit.de/index.php?page…3353#post183353
    if not IsInt($int) then return seterror(-1,0,-1)
    if $int<0 or $int>12 then return seterror(-1,0,-1)
    $bytecode="0xB801000000BA000000008B4C240483F9017612B80000000083F90C770889C849E80A0000008B7C24088907895704C3BA00000000F7E1497405E8F1FFFFFFC3"
    $tCodeBuffer = DllStructCreate("byte["&stringlen($bytecode)/2-1&"]") ;Speicher für den assemblercode belegen
    DllStructSetData($tCodeBuffer, 1,$bytecode) ;assemblercode in speicher schreiben
    $struct=dllstructcreate("uint64") ;64 Bit-Zahl, hier wird das Ergebnis EDX:EAX gespeichert
    $a = DllCall("user32.dll", "uint", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer),"int",$int ,"ptr",DllStructGetPtr($struct), "int", 0,"int",0);bytecode aufrufen, rückgabe in a[0]
    if @error then return seterror(-1,0,-1)
    return $a[0]
    endfunc

    [/autoit]

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (4. September 2010 um 11:45)