1

Тема: AHK: Преобразование типов данных.

Уважаемые форумчане, не подскажите как правильно перевести 4 байта информации в hex, в тип данных float point? Может у кого то есть готовая библиотека или функция? Просто я не могу ни как разобраться в самом типе данных float point. С этими мантиссами и экспонентами хрен разберешься... Вот что нашел:
Переменная типа float point внутренне состоит из трех компонентов: 
-  знак,
-  8-разрядная экспонента по основанию 2,
-  32-разрядная мантисса.
Формулы разные везде про этот тип разные. Вот:
F=(-1)^s2(e-127)(1+M/2^23)
F - десятичное число
S - бит знака (32 бит)
E - смещенная экспонента (30-20 биты)
M - остаток от мантиссы (22-0 биты)
Правильная ли эта формула?
Я понимаю что нужно в биты разбить hex строку, но все же как все это сделать то?

2 (изменено: Alectric, 2017-08-11 18:51:31)

Re: AHK: Преобразование типов данных.

Тоже интересует этот вопрос.

С картинкой нагляднее будет.
http://forum.script-coding.com/misc.php?action=pun_attachment&item=1378&download=0

Вот здесь пишут что формула - m*2**e ("мантисса" * (2 в степени "экспонента")), может это и есть нужная формула.

Учебник S7 пишет:

Переменная типа REAL внутри состоит из следующих трех компонентов: знака (31-
й бит), 8-битной экспоненты по базе 2 (биты с 23-го по 30-ый) и 23-битной мантиссы
(биты с 0-го по 22-ой). Знак может принимать значения «0» (положительное) и «1»
(отрицательное). Перед сохранением экспоненты к ней добавляется постоянное зна-
чение (смещение, +127), поэтому она отображает диапазон значений от 0 до 255.
Мантисса представляет дробную часть числа. Целая часть мантиссы не сохраняется,
так как она всегда равна 1 (в случае нормализованного числа с плавающей точкой)
или 0 (в случае ненормализованного числа с плавающей точкой). В таблице показан
внутренний диапазон чисел с плавающей точкой.

Страница 163 pdf.

Post's attachments

Безымянный.png 7.9 kb, file has never been downloaded. 

You don't have the permssions to download the attachments of this post.
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

3

Re: AHK: Преобразование типов данных.

NumPut, оно?

4 (изменено: Alectric, 2017-08-11 19:51:38)

Re: AHK: Преобразование типов данных.

Вот это я затупил...
Там же есть float.


NumPut(data,var,"Float")

Наверное так.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

5

Re: AHK: Преобразование типов данных.

Alectric, именно так. Ещё есть StrPut - это уже для строк, так и кодировки выбирай на свой вкус и цвет.

6

Re: AHK: Преобразование типов данных.

Alectric
Преобразование происходит при записи, а не при чтении.

7 (изменено: Alectric, 2017-08-11 19:51:52)

Re: AHK: Преобразование типов данных.

YMP, я не так понял.
Имеются данные в виде HEX строки которые представляют Float и нужно их снова записать в переменную NumPut'ом чтобы получить число с точкой. Поправил код выше.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

8

Re: AHK: Преобразование типов данных.

А разве АНК понимает float, представленный в виде хекса? Если только какое-то нововведение, а раньше хекс использовался только для целых.

Или это дробное число, у которого дробная часть нулевая?

9 (изменено: Alectric, 2017-08-11 20:10:42)

Re: AHK: Преобразование типов данных.

YMP пишет:

Или это дробное число, у которого дробная часть нулевая?

Нет, это дробное число которое в хексе зашифровано знаком, мантиссой и экспонентой.

Всегда были проблемы с дробями...

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

10

Re: AHK: Преобразование типов данных.

Тогда NumPut его не поймёт, как дробное. Оно будет воспринято, как целое, потом преобразовано из как бы целого во float, и на выходе будет белиберда.

11

Re: AHK: Преобразование типов данных.

Надо тогда просто писать хекс в буфер побайтно. Т.е. каждую пару символов писать, как uchar.

12

Re: AHK: Преобразование типов данных.

Вещественный тип данных.
Интересует 4х байтный с одинарной точностью:
Single(с одинар ной точностью)  от 1.5х10Е-45 до 3.4х10Е38

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

13

Re: AHK: Преобразование типов данных.

Raven, будет возможность, напиши HEX данные для заранее известного real числа, а лучше для двух разных чисел.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

14

Re: AHK: Преобразование типов данных.

Вот так можно хекс получить.


f := 123.456
VarSetCapacity(buf, 4, 0)
NumPut(f, buf, 0, "float")
hex := ""
SetFormat, Integer, H
Loop, 4
{
    hex .= SubStr("0" . SubStr(NumGet(buf, A_Index - 1, "uchar"), 3), -1)
}

MsgBox, % hex

15

Re: AHK: Преобразование типов данных.

Вместо

hex .= SubStr("0" . SubStr(NumGet(buf, A_Index - 1, "uchar"), 3), -1)

лучше

hex .= Format( "{:02X}", *(&buf + A_Index - 1) )

И

SetFormat, Integer, H

не нужно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

16

Re: AHK: Преобразование типов данных.

Суть вопроса была из HEX получить Float (из f31ce7d получить 23.54321 (цифры от балды, только суть)), но и этот код может кому-то пригодится.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

17

Re: AHK: Преобразование типов данных.

Из f31ce7d не получится, количество знаков должно быть чётным.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

18

Re: AHK: Преобразование типов данных.

Alectric пишет:

Суть вопроса была из HEX получить Float (из f31ce7d получить 23.54321 (цифры от балды, только суть)), но и этот код может кому-то пригодится.

Так вам нужна была пара чисел дробных в хекс-виде, я и показал, как вы можете их получить.

19 (изменено: Alectric, 2017-08-11 21:54:27)

Re: AHK: Преобразование типов данных.

Наоборот. В предыдущей теме мы обсуждали как получать данные из ПЛК (программируемый логический контроллер) с помощью dll. Результат работы dll - HEX строка, являющаяся копией памяти ПЛК в которой содержится значение Real представленное на картинке во втором посте. Из этой HEX строки необходимо получить Float число десятичного вида (123.456).

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

20

Re: AHK: Преобразование типов данных.

teadrinker пишет:

Из f31ce7d не получится

Alectric пишет:

(цифры от балды, только суть)

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

21

Re: AHK: Преобразование типов данных.

Так а в чём проблема превратить hex в число по тому же алгоритму, только в обратную сторону?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

22

Re: AHK: Преобразование типов данных.

Alectric пишет:

Raven, будет возможность, напиши HEX данные для заранее известного real числа, а лучше для двух разных чисел.

Это не вы разве писали? Я вам показал, как вы можете сами получить эти данные.

23

Re: AHK: Преобразование типов данных.

Проблема в том что голова уже не варит... пойду отдыхать.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

24

Re: AHK: Преобразование типов данных.

Уважаемые форумчане, всем спасибо за развернутые ответы. Был в дороге, поэтому не было меня на форме. Весь предоставляемый код который вы дали, смогу проверить только в понедельник, так как нахожусь в отъезде. Будут дельные советы или какой либо код прошу не стесняться и оставлять все это здесь, на благо общественности.

25

Re: AHK: Преобразование типов данных.

HexToFloat(value)
{
    Return, (1 - 2 * (value >> 31)) * (2 ** ((value >> 23 & 255) - 150)) * (0x800000 | value & 0x7FFFFF)
}

FloatToHex(value)
{
   format := A_FormatInteger
   SetFormat, Integer, H
   result := DllCall("MulDiv", Float, value, Int, 1, Int, 1, UInt)
   SetFormat, Integer, %format%
   Return, result
}

26 (изменено: teadrinker, 2017-08-12 02:23:56)

Re: AHK: Преобразование типов данных.

MsgBox, % FloatToHex(123.456)

FloatToHex(value)
{
   Return Format( "0x{:X}", DllCall("MulDiv", Float, value, Int, 1, Int, 1, UInt) )
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

27

Re: AHK: Преобразование типов данных.


MsgBox, % HexToFloat(0x42F6E979)

HexToFloat(x) {
   DllCall("RtlMoveMemory", "FloatP", f, "UIntP", x, "Uint", 4)
   Return f
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

28 (изменено: teadrinker, 2017-08-12 03:40:11)

Re: AHK: Преобразование типов данных.

Тогда так:

MsgBox, % FloatHexConverter(123.456)
MsgBox, % FloatHexConverter(0x42F6E979)

FloatHexConverter(source)  {
   if source is Float
      isSourceFloat := true
   DllCall( "RtlMoveMemory", isSourceFloat ? "UIntP" : "FloatP", result
                           , isSourceFloat ? "FloatP" : "UIntP", source
                           , Ptr, 4 )
   Return isSourceFloat ? Format("0x{:X}", result) : result
}

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

29

Re: AHK: Преобразование типов данных.

Может ещё Round добавить.

Return isSourceFloat ? Format("0x{:X}", result) : Round(result, 3)
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

30

Re: AHK: Преобразование типов данных.

Не, заранее же неизвестно, до какого знака округлять.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

31

Re: AHK: Преобразование типов данных.

Но в зависимости от целого должно быть как то известно какова возможная точность дроби, собственно и в примере уже не то число, вместо .456000 выходит .456001.


 Hex := FloatHexConverter(99999.99)  ;	max 2
MsgBox, % FloatHexConverter(Hex, 6)

 Hex := FloatHexConverter(9999.999)  ;	max 3
MsgBox, % FloatHexConverter(Hex, 6)

 Hex := FloatHexConverter(999.9999)  ;	max 4
MsgBox, % FloatHexConverter(Hex, 6)

FloatHexConverter(source, Round = 0)  {
   if source is Float
      isSourceFloat := true
   DllCall( "RtlMoveMemory", isSourceFloat ? "UIntP" : "FloatP", result
                           , isSourceFloat ? "FloatP" : "UIntP", source
                           , Ptr, 4 )
   Return isSourceFloat ? Format("0x{:X}", result) : result   ;	Round(result, Round)
}

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

32 (изменено: teadrinker, 2017-08-12 14:23:47)

Re: AHK: Преобразование типов данных.

serzh82saratov пишет:

Но в зависимости от целого должно быть как то известно какова возможная точность дроби

Не совсем понял, но скорее всего нет:

MsgBox, % FloatHexConverter(123.456) . "`n" . FloatHexConverter(123.456001)

FloatHexConverter(source)  {
   if source is Float
      isSourceFloat := true
   DllCall( "RtlMoveMemory", isSourceFloat ? "UIntP" : "FloatP", result
                           , isSourceFloat ? "FloatP" : "UIntP", source
                           , Ptr, 4 )
   Return isSourceFloat ? Format("0x{:X}", result) : result
}

Можно, конечно, добавить параметр, определяющий до какого знака округлять, но имхо это будет не очень красиво, т. к. в случае конвертации float в hex он будет лишним.

serzh82saratov пишет:

примере уже не то число, вместо .456000 выходит .456001

Это нормально, действия с float-числами всегда осуществляются с определённой погрешностью, это нужно учитывать.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

33

Re: AHK: Преобразование типов данных.

Всем откликнувшемся большое спасибо! Код отлично подходит под мои нужды.