#include <EditConstants.au3>
#include <WindowsConstants.au3>
;By Sprenger120
Global Const $iMaxInt32 = 4294967295
Opt("GUIOnEventMode", 1)

GUICreate("Optimized DIV Calc", 265, 190)
GUISetOnEvent(-3, "_Exit")
GUICtrlCreateLabel("Divisor:", 2, 2, 39, 17)
$cDivisor = GUICtrlCreateInput("", 56, 0, 209, 21, $ES_NUMBER)
$cStart = GUICtrlCreateButton("Start", 0, 172, 265, 17)
GUICtrlSetOnEvent(-1, "_Calc")
GUICtrlCreateLabel("Ergebnis:", 2, 32, 48, 17)
$cAusgabe = GUICtrlCreateEdit("", 56, 32, 209, 129, BitOR($ES_AUTOVSCROLL, $ES_READONLY, $WS_VSCROLL))

GUISetState(@SW_SHOW)
While Sleep(50)
WEnd

Func _Calc()
	Local $iNum, $kmin = 1, $kmax = 0, $r, $i, $k, $a, $z, $zmin, $zmax
	Local $iMulVal, $iEinfachTest, $iBinaryTest, $sString, $iUeberlaufVal

	$iNum = Int(GUICtrlRead($cDivisor))
	If Not StringRegExp($iNum, "^\d+$") Or $iNum > 999999 Then Return

	;Part by Andy
	For $i = 1 To 32
		If 2 ^ ($i - 1) > $iNum Then ExitLoop
	Next

	For $r = $i To 22 ;maximales shift festlegen bis maximal 25
		$k = 2 ^ $r / $iNum
		If ($k - Int($k)) < $kmin Then
			$kmin = ($k - Int($k))
			$zmin = $r
		EndIf
		If ($k - Int($k)) > $kmax Then
			$kmax = ($k - Int($k))
			$zmax = $r
		EndIf
	Next
	$a = 1 - ($kmax - Int($kmax))
	If $a > $kmin Then ;kmin ist minimum
		$z = $zmin
	Else
		$z = $zmax
	EndIf

	;Genauigkeit erhöhen
	$iMulVal = Int(2 ^ $z / $iNum)

	While 1
		$iBinaryTest = $iNum * 2 * $iMulVal
		$iBinaryTest = BitShift($iBinaryTest, $z)
		If $iBinaryTest <> 2 Then
			$iMulVal += 1
			ContinueLoop
		EndIf
		ExitLoop
	WEnd

	$iUeberlaufVal = Int($iMaxInt32 / $iMulVal)
	$iUeberlaufVal -= 1 ;-1 zur sicherheit ^^

	$sString &= "// Division durch " & $iNum & @CRLF & @CRLF
	$sString &= "// Ohne Überlauf bis " & "(-)" & $iUeberlaufVal & @CRLF & @CRLF
	$sString &= "//Assembler:" & @CRLF
	$sString &= "mov eax, " & $iNum * 2 & @CRLF
	$sString &= "mov edx, " & $iMulVal & @CRLF
	$sString &= "mul edx" & @CRLF
	$sString &= "shr eax, " & $z & @CRLF & @CRLF

	$sString &= "//C++" & @CRLF
	$sString &= "int Zahl = " & $iNum * 2 & ";" & @CRLF
	$sString &= "Zahl *= " & $iMulVal & ";" & @CRLF
	$sString &= "Zahl >>=" & $z & ";" & @CRLF

	GUICtrlSetData($cAusgabe, $sString)
EndFunc   ;==>_Calc

Func _Exit()
	Exit
EndFunc   ;==>_Exit