Что нового

[Математика] _DecToString - Преобразование DEC в другие системы счисления

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Код:
ConsoleWrite( _DecToString( Dec( "5DF3FFEF1" ) ) & @LF )


;#Return
;value=string
;@Extended - String len
Func _DecToString( $iDec, $iProv = 36, $iLen = 0, $sBase = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ) ;2 - BN, 10 - DEC, 16 - HEX, 36 - 09AZ
	Local $Idx, $IdxTo = 1, $iTmp = 1, $iExp, $aBase, $sStr_f
	; ---
	$aBase = StringSplit( $sBase, "" )
	Select
		Case $iProv < 2 Or $iProv > 36
			Return SetError( 1, 0, 0 )
		Case $aBase[0] < $iProv
			Return SetError( 2, 0, 0 )
	EndSelect
	; *
	While 1
		$iTmp *= $iProv
		If $iDec < $iTmp Then _
			ExitLoop

		$IdxTo += 1
	WEnd
	For $Idx = $IdxTo To 1 Step -1
		$iExp = $iProv^$Idx
		$iTmp = Int( Mod( $iDec + $iExp, $iExp ) / ( $iExp / $iProv ) )
		$sStr_f &= $aBase[$iTmp + 1]
	Next
	; *
	If $iLen Then
		$sStr_f = StringRight( $sStr_f, $iLen )
		For $Idx = 1 To $iLen - StringLen( $sStr_f ) Step 1
			$sStr_f = "0" & $sStr_f
		Next
	EndIf
	; *
	Return SetError( 0, $IdxTo, $sStr_f )
EndFunc


Хотелось бы по возможности увидеть более "лучшие" варианты (так как писал сам), ибо ранее не приходилось вручную переводить в другие системы счисления (главным образом не устраивает текущая скорость).
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Выбирай
http://autoit-script.ru/index.php/topic,9250.0.html
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Или здесь конвертирует в любую систему счисления и обратно. Основная идея - задавать на входе символы из которых состоит искомая сс.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
В справке раздел "ConvertingNumbers" (_DecToNum). На эту тему я даже утилиту сделал с тем же названием.
 

palub

Новичок
Сообщения
32
Репутация
3
Позвольте пожалуйста задать возможно глупый вопрос , ну или выдать свою мысль, вам решать) :stars:
Для моего понимания Dec это числовой представление шестнадцатеричной строки, то есть: HEX это число от 0 до F (0..9ABCDEF), а числовой представление это, например, F=16 или A = 10..
Так вот к чему я это, для чего нужно вообще преобразование между типом данных если Автоит сам по себе (вроде-бы) не имеет такого понятия как ТИПЫ данных, ну или (из delphi) StrToInt тот не нужно, так как автоит думает что $go = '1'; и $go2 = 1; это одно и то же..
Код:
$go = '1'; // ну допустим что это String
$go2 = 1; // а это Int
MsgBox(0, '', $go + $go2); // =2


Поэтому не вижу смысла писать замудренную функцию DecToStr на автоите, так как проще всего просто показать пот так:
Код:
$dec = Dec('dec777'); // hex значение 'dec777' преобразуем в  DECIMAL (Dec)
;// этим самым уже получаем числовое представление этой строки, то есть 14600055
;// теперь уже спокойно выводим это, куда угодно, как string
MsgBox(0, '', $dec);


А вот попробуйте теперь то же самое сделать в делфи
то есть
Код:
..
var
dec: integer;
begin 
dec := 123;
ShowMessage(dec); {тут то вы получаете ошибку, причем грубую, 
поэтому это не верный пример, верно будет вот так: 
ShowMessage(IntToStr(dec));}
end;
..
Ну или я просто задачи не понял) Возможно это какая то своеобразная шифровка...
:stars:
 
Автор
firex

firex

AutoIT Гуру
Сообщения
943
Репутация
208
palub [?]
Для моего понимания Dec это числовой представление шестнадцатеричной строки, то есть: HEX это число от 0 до F (0..9ABCDEF), а числовой представление это, например, F=16 или A = 10..
DEC - это десятичная система счисления (та система, которой мы пользуемся в повседневной жизни). Шестнадцатеричную строку можно представить в любой системе счисления (точно так же, как и любую в ней).

для чего нужно вообще преобразование между типом данных если Автоит сам по себе (вроде-бы) не имеет такого понятия как ТИПЫ данных
Да, в AutoIt все переменные Variant, однако какое отношение этот факт имеет к теме? Мы тут представляем данные в разных системах счисления, а не в разной форме.

Код:
VarGetType

Посмотрите пример к функции. Да, AutoIt способен "интуитивно" распознавать типы при сравнении / присвоении, однако делает он это далеко не всегда правильно. Поэтому за типами все же лучше следить.
 
Автор
firex

firex

AutoIT Гуру
Сообщения
943
Репутация
208
До кучи вариант преобразующий обратно в Dec (зная базу и номер системы счисления), идея взята отсюда (спасибо inververs'у):
http://www.autoitscript.com/forum/topic/39010-decimal-to-any-base/

Код:
Func _StringToDec( $sStr, $iProv = 16, $sBase = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" )
	Local $Idx, $IdxTo, $Jix, $vTmp, $iExp, $aBase, $iDec_f = 0
	; ---
	$aBase = StringSplit( $sBase, "" )
	$sStr = StringRegExpReplace( $sStr, "^0+", "" )
    Select
        Case $iProv < 2 Or $iProv > 36
            Return SetError( 1, 0, 0 )
        Case $aBase[0] < $iProv
            Return SetError( 2, 0, 0 )
		Case $sStr = ""
			Return 0
    EndSelect
    ; *
	$IdxTo = StringLen( $sStr )
	For $Idx = 1 To $IdxTo Step 1
		$vTmp = StringMid( $sStr, $Idx, 1 )
		For $Jix = 1 To $iProv Step 1
			If $vTmp = $aBase[$Jix] Then
				$vTmp = $Jix
				ExitLoop
			ElseIf $Jix = $iProv Then
				Return SetError( 3, 0, 0 )
			EndIf
		Next
		; *
		$iExp = $iProv^($IdxTo-$Idx)
		$iDec_f += $iExp*($vTmp-1)
	Next
	; *
	Return $iDec_f
EndFunc



Добавлено:
Сообщение автоматически объединено:

Может кому пригодится, набросал пример генерации базы:
Код:
#Include <Array.au3>

$hGui = GUICreate( "", 560, 24, -1, -1, 0x94CB00CC, 0x00050181 )
GUISetState( @SW_SHOW, $hGui )

$iInput = GUICtrlCreateInput( "", 2, 2, 556, 20 )
GUICtrlSetFont( $iInput, 10, 400, 0, "Luicide Console" )

Local $aBase = StringSplit( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "" )

Local $aMain[$aBase[0]+1] = [0]
For $Idx = 1 To $aBase[0] Step 1
	$aMain[$Idx] = "X"
Next

Do
	If $aMain[0] < $aBase[0] Then
		$iRand = Random( 1, $aBase[0], 1 )
		$aMain[$aMain[0]+1] = $aBase[$iRand]

		For $Idx = $aMain[0] To 1 Step -1
			If $aMain[$Idx] == $aBase[$iRand] Then _
				ExitLoop
		Next
		If Not $Idx Then
			$aMain[0] += 1
		EndIf
		GUICtrlSetData( $iInput, _ArrayToString( $aMain, "", 1 ) )
	EndIf
Until GUIGetMsg() = -3
 
Верх