Что нового

Как работать с double типами данных?

V

VitAl2013

Гость
Непосредственно сейчас меня мучает вопрос как число 420 записать в файл например 1.txt так чтоб при открытии его через WinHex я получал не 34 32 30 и не 01 A4, а 00 00 00 00 00 40 7A 40? Такое возможно если мы работаем с double переменными.

Вообще интересно знать как проводить работу с Double переменными. Что для этого есть у AutoIT?

В статье Language Reference - Datatypes из помощи к AutoIT они определяются, но чтоже дальше?
 

Olivaw

Новичок
Сообщения
1
Репутация
0
$file = FileOpen("C:\test.txt", 17)
$x1 = 420.0
FileWrite($file, $x1)
FileClose($file)
 
Автор
V

VitAl2013

Гость
:smile: да я так тоже получил... но как провести обратный процесс? Особенно если это число проскакивает както так
Код:
AB CD EF 00 40 7A 40 E0 10
Допустим я вычленю эти
Код:
40 7A 40
но как из них получить обратно 420.0?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Код:
#Include <WinAPI.au3>

Global $tDouble, $pDouble, $iSize, $iBytes

$x1 = 420.16

$tDouble = DllStructCreate('double')
$pDouble = DllStructGetPtr($tDouble)
$iSize = DllStructGetSize($tDouble)

; Запись в файл

$hFile = _WinAPI_CreateFile('test.dat', 1, 4)
DllStructSetData($tDouble, 1, $x1)
_WinAPI_WriteFile($hFile, $pDouble, $iSize, $iBytes)
_WinAPI_CloseHandle($hFile)

; Чтение из файла

$hFile = _WinAPI_CreateFile('test.dat', 2, 2)
_WinAPI_ReadFile($hFile, $pDouble, $iSize, $iBytes)
_WinAPI_CloseHandle($hFile)

$x1 = DllStructGetData($tDouble, 1)
ConsoleWrite($x1 & @CR)
 
Автор
V

VitAl2013

Гость
А нельзя ли закомментировать - я не знаком с dll структурой и тем как Windows c ней работает. Не совсем понимаю зачем мы должны делать все эти DllStructGetPtr, DllStructCreate использовать $iSize и неопределённый(?) $iBytes.

Или другой вариант. Я уже имею набор hex в виде "40 7A 40" и мне его надо перевести в asci или string. Мне нужна функция которая воспринимала данный код как закодированный double. Чтото вроде
Код:
func decode($hex)
...
return $string
endfunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Вот пример с FileRead() + FileWrite(). Но, IMHO с этими функциями лучше работать только с текстом.

Код:
$x1 = 420.125

; Запись
$hFile = FileOpen('test.dat', 18)
FileWrite($hFile, $x1)
FileClose($hFile)

; Чтение
$hFile = FileOpen('test.dat', 16)
$bData = FileRead($hFile, 8)
FileClose($hFile)
ConsoleWrite(_Decode($bData) & @CR)

; Без комментариев :)
Func _Decode($bValue)

	Local $tStruct1, $tStruct2

	$tStruct1 = DllStructCreate('uint64')
	DllStructSetData($tStruct1, 1, $bValue)
	$tStruct2 = DllStructCreate('double', DllStructGetPtr($tStruct1))
	Return DllStructGetData($tStruct2, 1)
EndFunc   ;==>_Decode
 
Автор
V

VitAl2013

Гость
Делаю так:
Код:
$x1  = 420.125
ConsoleWrite($x1 & @CR)

; Запись
$hFile = FileOpen('test.dat', 18)
FileWrite($hFile, $x1)
FileClose($hFile)

; Чтение
$hFile = FileOpen('test.dat', 16)
$bData = FileRead($hFile, 8)
ConsoleWrite($bData & @CR)
$bData = "0x0000000000427A40"
FileClose($hFile)
ConsoleWrite(_Decode($bData) & @CR)
ConsoleWrite(_Decode("427A40") & @CR)

; Без комментариев :)
Func _Decode($bValue)

    Local $tStruct1, $tStruct2

    $tStruct1 = DllStructCreate('uint64')
    DllStructSetData($tStruct1, 1, $bValue)
    $tStruct2 = DllStructCreate('double', DllStructGetPtr($tStruct1))
    Return DllStructGetData($tStruct2, 1)
EndFunc   ;==>_Decode

Получаю:
Код:
420.125
0x0000000000427A40
2.15248196539848e-317
2.10966030774212e-321
Почему не работает?

Я предполагаю открывать файл через
Код:
StringToBinary()
что должно давать код вроде:
Код:
ABCDEF0123456789
Далее вычленять например
Код:
234567
менять 23 на 40
Код:
404567
и читать как double переменную.


Ищё вот, делаю так:
Код:
#Include <WinAPI.au3>

Global $tDouble, $pDouble, $iSize, $iBytes

$tDouble = DllStructCreate('double')
ConsoleWrite($tDouble & @CR)
$pDouble = DllStructGetPtr($tDouble)
ConsoleWrite($pDouble & @CR)
$iSize = DllStructGetSize($tDouble)
ConsoleWrite($iSize & @CR)

$hFile = _WinAPI_CreateFile('test.dat', 2, 2)
$hFile = "0x00000000"
$hFile = "0x000006D0"
ConsoleWrite($hFile & @CR)
_WinAPI_ReadFile($hFile, $pDouble, $iSize, $iBytes)
_WinAPI_CloseHandle($hFile)

$x1 = DllStructGetData($tDouble, 1)
ConsoleWrite($x1 & @CR)


Получаю:
Код:
0x01B57800
8
0x000006D0
420.16

Но если поменять
Код:
$hFile = "0x000006D0"
на скажем так
Код:
$hFile = "0x00407A40"
то получаю
Код:
0x01B57800
8
0x00407A40
0
Почему 0? ЧТо почитать чтоб понять?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
VitAl2013 сказал(а):
Почему не работает?

Код:
$bData = Binary("0x0000000000427A40")


VitAl2013 сказал(а):
Код:
$hFile = _WinAPI_CreateFile('test.dat', 2, 2)
$hFile = "0x00000000"
$hFile = "0x000006D0"
ConsoleWrite($hFile & @CR)
_WinAPI_ReadFile($hFile, $pDouble, $iSize, $iBytes)
_WinAPI_CloseHandle($hFile)


Но если поменять
Код:
$hFile = "0x000006D0"
на скажем так
Код:
$hFile = "0x00407A40"
то получаю
Код:
0x01B57800
8
0x00407A40
0
Почему 0? ЧТо почитать чтоб понять?

:wacko:

$hFile - это указатель на файл, и его трогать нельзя. Что ты пытался здесь сделать?
 
Автор
V

VitAl2013

Гость
Я думал это внутренности файла ;D Я их выводил же в консоль... и недопёр что это же хэндл. Думал это он прямо значение выдаёт.

Подобью, что получилось:
Код:
ConsoleWrite(_Decode("00000000000407A40") & @CR)
ConsoleWrite(_Decode("407A40") & @CR)

Func _normalize($hex)
	if StringLen($hex)<=16 then
		for $a = 16-StringLen($hex) to 1 step -1
			$hex = "0"&$hex
		next
		$result = "0x"&$hex
	else
		ConsoleWrite("It's bigger than 16 digits" & @CR)
		$result = ""
	endif
	return $result
EndFunc

Func _Decode($bString)
	$bValue = Binary(_normalize($bString))

    Local $tStruct1, $tStruct2

    $tStruct1 = DllStructCreate('uint64')
    DllStructSetData($tStruct1, 1, $bValue)
    $tStruct2 = DllStructCreate('double', DllStructGetPtr($tStruct1))
    Return DllStructGetData($tStruct2, 1)
EndFunc
 
Верх