может просто столбиком?.. ;)
Код:
ConsoleWrite(_BinaryFacrorial(100) &@CRLF)
; Факториал
Func _BinaryFacrorial($iNum)
Local $res = Binary("0x01")
For $i=1 To $iNum
$res = _BinaryMult($res, Binary("0x"& Hex($i,2)))
Next
Return $res
EndFunc ; ==> _BinaryFacrorial()
; Умножение двух бинарных переменных как чисел (столбиком ;) )
Func _BinaryMult($bin1, $bin2)
If IsBinary($bin1)=0 Or IsBinary($bin2)=0 Then Return SetError(1)
Local $z1 = BinaryLen($bin1), $t1 = DllStructCreate("byte["& $z1 &"]")
DllStructSetData($t1, 1, $bin1)
Local $bin0 = Binary(Chr(0))
For $i=$z1*8-1 To 0 Step -1
If BitAND(DllStructGetData($t1,1,BitShift($i,3)+1),BitRotate(128,-BitAND($i,7))) Then $bin0 = _BinaryAdd($bin0, $bin2)
$bin2 = _Binary2x($bin2)
Next
Return $bin0
EndFunc ; ==> _BinaryMult()
; сложение двух бинарных переменных, как чисел
Func _BinaryAdd($bin1, $bin2)
If IsBinary($bin1)=0 Or IsBinary($bin2)=0 Then Return SetError(1)
Local $z1=BinaryLen($bin1), $z2=BinaryLen($bin2)
Local $z0=$z1, $i, $x=0
If $z2 > $z0 Then $z0 = $z2
Local $tb1 = DllStructCreate("byte["& $z0-$z1+1 &"];byte["& $z1 &"]")
Local $tb2 = DllStructCreate("byte["& $z0-$z2+1 &"];byte["& $z2 &"]")
Local $ti1 = DllStructCreate("byte;byte["& $z0 &"]", DllStructGetPtr($tb1))
Local $ti2 = DllStructCreate("byte;byte["& $z0 &"]", DllStructGetPtr($tb2))
Local $tb0 = DllStructCreate("byte;byte["& $z0 &"]")
DllStructSetData($tb1, 2, $bin1)
DllStructSetData($tb2, 2, $bin2)
For $i = $z0 To 1 Step -1
$x = BitShift($x, 8)
$x += DllStructGetData($ti1, 2, $i) + DllStructGetData($ti2, 2 ,$i)
DllStructSetData($tb0, 2, $x, $i)
Next
If Not(BitAND($x, 0x100)) Then Return DllStructGetData($tb0, 2)
Return Binary(Chr(1)) & DllStructGetData($tb0, 2)
EndFunc ; ==> _BinaryAdd()
; умножение бинарных данных на 2, т.е.
; сдвиг влево с добавлением нулевого бита
Func _Binary2x($bin)
If IsBinary($bin)=0 Then Return SetError(1)
Local $z = BinaryLen($bin), $i, $t, $x=0
If $z=0 Then Return Binary("0x00")
$t = DllStructCreate("byte["& $z &"]")
DllStructSetData($t, 1, $bin)
For $i = $z To 1 Step -1
$x = BitShift($x, 8)
$x = BitOR($x, BitRotate(DllStructGetData($t,1,$i), 1, "W"))
DllStructSetData ($t, 1, $x, $i)
Next
If Not(BitAND($x, 0x100)) Then Return DllStructGetData($t, 1)
Return Binary(Chr(1)) & DllStructGetData($t, 1)
EndFunc ; ==> _Binary2x()
подсказка: для перевода в другую систему счисления нужно добавить вычитание/деление
P.S. проверял этим: Hex Calculator for Programmers and Cryptanalysts
|