Что нового

[Математика] Перевод числа между системами счисления

amel27

Продвинутый
Сообщения
146
Репутация
55
AutoIt: 3.3.6.1
Версия: 1.0
Категория: Математика

Описание: Перевод беззнакового числа из двоичной в десятичную систему счисления
Код:
Код:
; =====================================================
; Имя............: _StringUBin2Dec
; Использование..: _StringUBin2Dec ($strBin)
; Параметры......: $strBin - двоичное число
; Результат......: Успех   - строка-десятичное число
;                  Неудача - пустая строка/@error=1
; Автор..........: amel27
; =====================================================
Func _StringUBin2Dec($sB)
  ; проверка переданной строки
  $sB = StringRegExpReplace($sB, "^0+", "")
  If StringRegExp($sB,"^[01]+$")=0 Then Return SetError(1,0,"")
  ; инициализация переменных и структур
  Local $zB = StringLen($sB)
  Local $zD = Int(Log(2)*$zB/Log(10))+1
  Local $tB = DllStructCreate("byte["& $zB &"]")
  Local $tD = DllStructCreate("byte["& $zD &"]")
  Local $pD = DllStructGetPtr($tD)
  Local $iD, $fC, $tR, $xD=$zD
  DllStructSetData($tB, 1, $sB)
  ; цикл по знакам двоичного числа (сдвиг влево)
  For $i=1 To $zB
    ; установка флага переноса
    $fC = BitAnd(0x0F, DllStructGetData($tB, 1, $i))
    ; цикл по знакам десятичного числа (сдвиг влево)
    For $j=$zD To $xD-1 Step -1
      $iD = DllStructGetData($tD,1,$j) ; прочитать знак
      $iD = BitAND(0x0F,$iD)           ; ASCII -> число
      If $iD>4 Then $iD+=3             ; корректировка
      $iD = BitRotate($iD,1)           ; сдвиг влево
      If $fC Then $iD=BitOR($iD,1)     ; применить флаг
      $fC = BitAND(0xF0, $iD)          ; установить флаг
	  $iD = BitOR(0x30, $iD)           ; число -> ASCII
      DllStructSetData($tD,1,$iD,$j)   ; сохранить знак
	  If $iD>0x30 Then $xD=$j          ; левая граница
    Next
  Next
  ; пропуск ведущих нулей в результате
  $tR=DllStructCreate("char["&$zD-$xD+1&"]",$pD+$xD-1)
  Return DllStructGetData($tR, 1)
EndFunc ; ==> _StringUBin2Dec()

Описание: Перевод беззнакового числа из десятичной в двоичную систему счисления
Код:
Код:
; =====================================================
; Имя............: _StringUDec2Bin
; Использование..: _StringUDec2Bin ($strDec)
; Параметры......: $strDec - десятичное число
; Результат......: Успех   - строка - двоичное число
;                : Неудача - пустая строка/@error=1
; Автор..........: amel27
; =====================================================
Func _StringUDec2Bin($sD)
  ; проверка переданной строки
  $sD = StringRegExpReplace($sD, "^0+", "")
  If StringRegExp($sD,"^\d+$")=0 Then Return SetError(1,0,'')
  ; инициализация переменных и структур
  Local $zD=StringLen($sD)
  Local $zB=Int(Log(10)*$zD/Log(2))+1
  Local $tD=DllStructCreate("byte["& $zD &"]")
  Local $tB=DllStructCreate("byte["& $zB &"]")
  Local $pB=DllStructGetPtr($tB)
  Local $iD, $fC, $fB, $tR, $fT, $xD=1
  DllStructSetData($tD, 1, $sD)
  ; счетчик бит исходного числа (кол-во сдвигов)
  For $i=0 To 4*$zD-1
    $fC = 0 ; сброс флага переноса
    $fT = 0 ; сброс флага проверки
	; цикл по знакам исходного числа (сдвиг вправо)
    For $j=$xD To $zD
      $iD=DllStructGetData($tD,1,$j) ; прочитать знак
      $iD=BitAND(0x0F,$iD)           ; ASCII -> число
      $fB=BitAND(0x01, $iD)          ; сохранить флаг
      $iD=BitShift($iD, 1)           ; сдвиг вправо
      If $fC Then $iD+=5             ; корректировка
      $fC = $fB                      ; восстановить флаг
	  $iD = BitOR(0x30,$iD)          ; число -> ASCII
      DllStructSetData($tD,1,$iD,$j) ; сохранить знак
	  If $fT =0 And $iD >0x30 Then
        $fT = 1   ; установка флага проверки
		$xD = $j  ; левая граница числа в буфере
      EndIf
    Next
    DllStructSetData($tB,1,BitOR(0x30,$fC), $zB-$i)
  Next
  ; пропуск ведущих нулей в результате
  For $i=1 To $zB
    If DllStructGetData($tB,1,$i) >0x30 Then ExitLoop
  Next
  $tR=DllStructCreate("char["& $zB-$i+1 &"]",$pB+$i-1)
  Return DllStructGetData($tR, 1)
EndFunc ; ==> _StringUDec2Bin()

Пример:
Код:
$sD="2010404970693222935699259370174"
$sB="11001010111111111100000000011111000000000111111111101010100000001111110101010000011111010101010111110"

ConsoleWrite("Исходное десятичное: "& $sD &@CRLF)
ConsoleWrite("Выходное десятичное: "& _StringUBin2Dec($sB) &@CRLF&@CRLF)
ConsoleWrite("Исходное двоичное: "  & $sB &@CRLF)
ConsoleWrite("Выходное двоичное: "  & _StringUDec2Bin($sD) &@CRLF)

Алгоритм: метод сдвига и коррекции
Источник: Злобин В.К., Григорьев В.Л. "Программирование арифметических операций в микропроцессорах"
Дополнительно: числа в неупакованном ASCII формате (цифра = байт), длина не ограничена
 
Верх