Что нового

[Данные, строки] Бинарное представление

Статус
Закрыто для дальнейших ответов.

DemkaDV

Новичок
Сообщения
16
Репутация
3
Уважаемые знатоки, требуется консультация, работаю с COM-портом, имею длину строки 14 Байт, как можно средствами Autoit проверить состояние каждого бита (0 или 1)? Ну или как преобразовать шестнадцатеричное представление (9B) к бинарному виду (10011011).
 

beliy

Продвинутый
Сообщения
372
Репутация
72
как преобразовать шестнадцатеричное представление (9B) к бинарному виду (10011011)

Код:
$a = "9B"

$b = _HexToBinaryString($a)

MsgBox(64, "HEX to BIN", "HEX value: " & $a & " = " & $b & "(BIN)")

Func _HexToBinaryString($HexValue)
Local $Allowed = '0123456789ABCDEF'
Local $Test,$n
Local $Result = ''
if $hexValue = '' then
SetError(-2)
Return
EndIf

$hexvalue = StringSplit($hexvalue,'')
for $n = 1 to $hexValue[0]
if not StringInStr($Allowed,$hexvalue[$n]) Then
SetError(-1)
return 0
EndIf
Next

Local $bits = "0000|0001|0010|0011|0100|0101|0110|0111|1000|1001|1010|1011|1100|1101|1110|1111"
$bits = stringsplit($bits,'|')
for $n = 1 to $hexvalue[0]
$Result &= $bits[Dec($hexvalue[$n])+1]
Next

Return $Result

EndFunc
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Когда-то делал для себя( c чьей-то помощью на форуме). Кстати и обратный перевод.
С трудом вспомнил где , но нашел.
Код:
#include <String.au3>
#include <Array.au3>	
Global $aBin2Codes[17]=[16,'0000','0001','0010','0011','0100','0101','0110','0111','1000','1001','1010','1011','1100','1101','1110','1111']
$strHex="9B"
$ResBIN=_HexToBin2($strHex)
MsgBox(64, "HEX to BIN", "HEX value: " & $strHex & " = " & $ResBIN & "(BIN)")	

$ResHEX=_Bin2ToHex($ResBIN)	
MsgBox(64, "BIN to HEX", "BIN value: " & $ResBIN & " = " & $ResHEX & "(HEX)")	
			
Func _HexToBin2($hexStr)
	Local $sString='0123456789ABCDEF'
	$bin2Rez=''
	For $i =1 To StringLen($hexStr)
		$hexFragment=StringMid($hexStr,$i,1)
		$iIndex=StringInStr ( $sString,$hexFragment)
		$bin2Rez &= $aBin2Codes[$iIndex]
	Next
	Return $bin2Rez
EndFunc ; ====> _HexToBin2
	
	
Func _Bin2ToHex($bin2Str)
	Local $sString='0123456789ABCDEF'
	$hexRez=''
	For $i =1 To StringLen($bin2Str) step 4
		$bin2Fragm=StringMid($bin2Str,$i,4)
		$iIndex=_ArraySearch($aBin2Codes,$bin2Fragm,0,0,0,1)
		$hexRez &= StringMid($sString,$iIndex,1)
	Next
	Return $hexRez
EndFunc ; ====> _Bin2ToHex

Может кому понадобится
 
Автор
D

DemkaDV

Новичок
Сообщения
16
Репутация
3
Оригинально конечно, решение в лоб, я понимаю что в Autoit все переменные типа Variant, а если у меня строка длиной 14 Байт, то это необходимо сначала перевести всю строку в двоичное представление - это 14*8 символов, затем включать обработку по позиции символа, но это же каменный век. Можно наверное вернуть как-то нужный бит из байта.
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Если пользоваться данными функциями не смотря в код, то я бы, например, вызывал бы их с параметром в виде 0x9B или "0x9B", как принято записывать hex-представление числа в AutoIt. А эти случаи в функциях не предусмотрены :(
 
Автор
D

DemkaDV

Новичок
Сообщения
16
Репутация
3
BinaryMid - возвращает не совсем то что нужно.
Код:
Local $binary = Binary(11100010)
$extract = BinaryMid($binary, 2, 2)
MsgBox(0, "", $extract)
MsgBox(0, "", $binary)

к примеру 1101010010111111010100100000000 - это 0x6A5FA900
BinaryMid с указанными параметрами вернет мне 0x5FA9

а необходимо вернуть значение (0 или 1) к примеру во втором байте (выделил жирным)
0110 1010 0101 1111 1010 1001 0000 0000
при этом скорость обработки при методе подстановки оставляет желать лучшего, на порту СOM скорость обмена 2400 и таких пакетов я получаю достаточно много за одну секунду.
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
Код:
; Author: Malkey
ConsoleWrite(IntToBin(0x9B) & @CRLF)

Func IntToBin($iInt) ; coded by Malkey
	Local $b = ""
	For $i = 1 To 32
		$b = BitAND($iInt, 1) & $b
		$iInt = BitShift($iInt, 1)
	Next
	Return $b
EndFunc   ;==>IntToBin


А вообще универсальное средство комбинация _NumToDec и _DecToNum позволяют конвертировать из люой разрядности число в любую разрядность.
 
Автор
D

DemkaDV

Новичок
Сообщения
16
Репутация
3
AZJIO - Ваш пример мне очень понравился, но я попробую все-таки использовать функции BitAND и BitShift с наложением маски
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
На всякий случай в обратную сторону:
Код:
; Author: Malkey
ConsoleWrite(BinToInt(111000) & @CRLF)

Func BinToInt($bin) ;coded by Malkey
	Local $aArr = StringSplit($bin, "", 2)
	Local $dec = 0
	For $i = UBound($aArr) - 1 To 0 Step -1
		If $aArr[$i] = "1" Then
			$dec = BitXOR($dec, BitShift(1, -(UBound($aArr) - 1 - $i)))
		EndIf
	Next
	Return $dec
EndFunc   ;==>BinToInt


Этот же пример с моей модернизацией (скорость чуть чуть быстрей, но при отсутствии проверки числа)
Код:
$timer = TimerInit()
$xxx = BinToInt(11100)
$timer = 'Время : ' & Round(TimerDiff($timer), 4) & ' мсек'
MsgBox(0, $timer, $xxx)

Func BinToInt($bin) ;coded by Malkey
	If StringRegExp($bin, '[^01]') Then Return SetError(1) ; проверка валидности двоичного числа
	Local $aArr = StringSplit($bin, ''), $iDec = 0
	For $i = $aArr[0] To 1 Step -1
		If $aArr[$i] = '1' Then
			$iDec = BitXOR($iDec, BitShift(1, -($aArr[0] - $i)))
		EndIf
	Next
	Return $iDec
EndFunc   ;==>BinToInt


Если что на wiki есть Snippets в разделе математики.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
OffTopic:
Надо будет почаще в справку заглядывать
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
DemkaDV,
Предупреждение За нарушение правил форума (пункт В.11):
Любые отрывки AutoIt кода необходимо заключать в тег [autoit]
autoit.gif
(подробнее), а обычный код соответственно в тег [code]
code.gif
(подробнее). Также большие выдержки текста помещайте под тег [spoiler]
spoiler.gif
(подробнее), там где это поддерживается естественно. Как в случае с названием темы, также короткое и эргономичное сообщение привлекает больше внимания, и шансы на получение конкретного ответа увеличиваются.


С уважением, ваш Модератор.




xaker,
Не надо отвечать в теме до того, как не исправлено то, из-за чего вынесено предупреждение.

Тема закрыта.
 
Статус
Закрыто для дальнейших ответов.
Верх