Форум: "Начинающим";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];
ВнизПомогите с преобразованием типов данных Найти похожие ветки
← →
vodvorezlaya (2006-09-01 16:32) [0]ДОБРОГО ВРЕМЕНИ СУТОК.
Есть данные 8-байт. Все 4 переменные типа word содержат в себе одно значение с плавающей точкой; (4byte*2=8byte)
Я знаю что формат этих данных float или real.
Как присвоить их одной переменной это понятно
допустим b4 самое старшее слово(2 байта).
b4*$ffffff+b3*$ffff+b2*$ff+b1=8 байт данных в формате LongWord
Ув. мастера вопрос:
Как перевести эти 8 бит данных в формат float или real но с плавающей запятой?
Есть догадки что через указатели.
Заранее спасибо.
← →
Elen © (2006-09-01 16:41) [1]
> vodvorezlaya
Воспользуйся типом Extended
← →
Dmitrij_K (2006-09-01 16:42) [2]в delfi приведение типов делается так
:= ВоЧтоПривести(Переменная);
Самый маленький тип с плавточкой Single занимает 4 байта т.е. в твои 8 байт можно запихнуть 2 переменные Single.
← →
han_malign © (2006-09-01 16:44) [3]1:
var
pw: array[0..3]of word;
_pf_pw: array[0..1]of single absolute pw;
_pd_pw: array[0..0]of double absolute pw;
2:
type
TExplicitCastFloat = packed record
case byte of
0: (pw: array[0..3]of word);
1: (pf: array[0..1]of single);
2: (pd: array[0..0]of double);
end;
3:
pf[0]:= single((@pw[0])^);
4:
move(pw[0], pf[0], sizeof(pf[0]));
← →
Сергей М. © (2006-09-01 16:48) [4]
> vodvorezlaya (01.09.06 16:32)
Хрень какая-то ...
Я нишута не понял.
приведи реальное содержимое того что имеется и того что должно получиться в результате
← →
DevilDevil © (2006-09-01 17:42) [5]Поддерживаю Сергей М. © (01.09.06 16:48) [4]
В Delphi нет типа float, есть single (4 байта). Типы real и double эквивалентны. Занимают 8 байт.
Если тебе надо "переконвертировать" double в single, то делает ся Очень Просто:var
d : double;
s : single;
begin
d := 18.144; // 8 байт
s := d; // 18.144; 4 байта
...
end;
Что касается массива (напримерARR = array[0..3] of word
), то преобразовать в double можно так:
d := double(ARR); // лично я сталкивался с ошибками
или
d := pdouble(@ARR[0])^;
НО самый крутой способ, как предложил han_malign © :var
ARR = array[0..3] of word;
d: double absolute ARR;
В таком случаеARR
иd
будут указывать на одну и туже область памяти. Можешь обращаться к массиву, а можешь сразу к double переменной
← →
vodvorezlaya (2006-09-04 08:19) [6]
> Хрень какая-то ...
>
> Я нишута не понял.
>
> приведи реальное содержимое того что имеется и того что
> должно получиться в результате
Народ. Вопрос не в том немного.
В шестнадцатеричных кодах нет знака запятой, она содержится в первых розрядах типа данных Real. Тоесть если присвоить переменной типа Real переменную LongWord то получится тоже значение, но без знаков после запятой, а они там есть. Оно попросту не воспримет тип LongWord как имеющий знаки после запятой.
Т.е. нужно чтоб оно поняло что этот тип нужно воспринимать как Float.
← →
vodvorezlaya (2006-09-04 08:20) [7]
> 1:
> var
> pw: array[0..3]of word;
> _pf_pw: array[0..1]of single absolute pw;
> _pd_pw: array[0..0]of double absolute pw;
> 2:
> type
> TExplicitCastFloat = packed record
> case byte of
> 0: (pw: array[0..3]of word);
> 1: (pf: array[0..1]of single);
> 2: (pd: array[0..0]of double);
> end;
> 3:
> pf[0]:= single((@pw[0])^);
> 4:
> move(pw[0], pf[0], sizeof(pf[0]));
Я понял, ты шаришь. А можна с небольшим комментарием.
Спасибо.
← →
vodvorezlaya (2006-09-04 08:51) [8]
> 1:
> var
> pw: array[0..3]of word;
А где младший и где старший розряды?
← →
Сергей М. © (2006-09-04 09:19) [9]
> В шестнадцатеричных кодах нет знака запятой, она содержится
> в первых розрядах типа данных Real
Ерунда какая-то)
type
PExtended = ^Extended;
..
var
MyArray: array[0..3] of Word;
MyFloatValue: Extended;
..
MyFloatValue := PExtended(@MyArray)^;
← →
Desdechado © (2006-09-04 11:27) [10]> переменные типа word содержат в себе одно значение с плавающей точкой
Тип Word не может содержать дробные числа.
Машинное представление дробных чисел базируется на мантиссе, порядке и основании. Ищи эти слова в гугле.
← →
han_malign © (2006-09-04 12:06) [11]
> Я понял, ты шаришь. А можна с небольшим комментарием.
> А где младший и где старший розряды?
- а вот это уже зависит от способа кодирования битового потока, big-endian(встречается, так же, как - network order, для значений выровненных на размер октета), или little-endian("обычное" представление для семейства x86 процессоров). В случае little-endian, если данные выровненны на размер октета - никаких дополнительных действий для разбора потока делать не надо - достаточно прямого приведения.
Что находится в самом битовом потоке - целиком и полностью на совести разработчика - если известно, что это стандартный double - нам не важно где у него мантисса, а где знак, нам важно заполнить 64-бита переменной типа double - 64-мя битами из потока, в соответсвии с правилами кодирования битового потока.
Выше, я, как раз, привел четыре способа прямого отбражения little-endian значений на разные типы данных.
← →
vodvorezlaya (2006-09-04 12:38) [12]
> 1:
> var
> pw: array[0..3]of word;
> _pf_pw: array[0..1]of single absolute pw;
> _pd_pw: array[0..0]of double absolute pw;
А эти способы разные?
Потому что первый не сработал.
han_malign какую литературу ты читал?
Там у меня вообще передача с контроллера Siemens Simatic S5 там какой то свой формат.
Как попробовать разными способами кодирования big-endian и little-endian.
> Ерунда какая-то)
Слушай han_malign, он шарит?
← →
Сергей М. © (2006-09-04 12:41) [13]
> vodvorezlaya (04.09.06 12:38) [12]
> Слушай han_malign, он шарит?
Шарит-шарит)
← →
Elen © (2006-09-04 12:50) [14]
> передача с контроллера Siemens Simatic S5
А ты что не знаеш протокола передачи? Ты используеш OPC сервер?
← →
vodvorezlaya (2006-09-04 13:01) [15]
> А ты что не знаеш протокола передачи? Ты используеш OPC
> сервер?
Нет, я написал сам модуль который по ком порту (через токовый преобразователь) передаёт данные к S5, могу код привести
:)
А что такое ОРС сервер?
Там что, дрова на Симатик есть?
← →
Elen © (2006-09-04 13:18) [16]
> vodvorezlaya
Для работы с контроллерами я всегда использую OPC сервер. Как правило с ним поставляется диск с дровами и OPC сервером, через который моя прога коннектиттся к устройству.Это программа-прослойка. Этот сервер сам преобразует данные получаемые с контроллера по нужному протоколу. я правда не знаю поставляет ли Сиеменс такие веши. Wago, ICPCon и подобные поставляют. ИМХО Самому писать протоколы (тем более к Семену) геморрой.
← →
han_malign © (2006-09-04 13:25) [17]http://www.runmode.com/usefulstuff.html
:
Notes on Simatic data storage
* Whenever you need to read or store values on Siemens PLCs, you must be aware that SIMATIC systems adopted the Big Endian byte order, see a brief description here: http://www.cs.umass.edu/~verts/cs32/endian.html
там же ссылки на протокол:
http://www.runmode.com/usefulstuff_files/AS511protocol_description.pdf
http://www.runmode.com/usefulstuff_files/0141_as511_komponente.zip
← →
han_malign © (2006-09-04 13:28) [18]компонент правда на немецком, но это мелочи...
← →
vodvorezlaya (2006-09-04 13:36) [19]
> ИМХО Самому писать протоколы (тем более к Семену) геморрой.
2 дня заняло написание полноценного модуля (не драйвера)
← →
vodvorezlaya (2006-09-04 13:42) [20]
> http://www.runmode.com/usefulstuff.html
> :
> Notes on Simatic data storage
> * Whenever you need to read or store values on Siemens
> PLCs, you must be aware that SIMATIC systems adopted the
> Big Endian byte order, see a brief description here: http:
> //www.cs.umass.edu/~verts/cs32/endian.html
> там же ссылки на протокол:
> http://www.runmode.com/usefulstuff_files/AS511protocol_description.
> http://www.runmode.com/usefulstuff_files/0141_as511_komponente.
> zip
У меня там другой протокол, но похоже
у меня RK-512
← →
Elen © (2006-09-04 13:46) [21]
> 2 дня заняло написание полноценного модуля
Будь у тебя нормальный OPC ты бы такими вопросами не задавался
← →
vodvorezlaya (2006-09-04 14:08) [22]
> Будь
Будь :)
Слушай,
> Elen
как решить проблему := inttostr(Edit1.Text); не проходит, ошибку какую - то лепис
← →
Сергей М. © (2006-09-04 14:17) [23]
> := inttostr(Edit1.Text); не проходит, ошибку какую - то
> лепис
мда ...
Начали за здравие, закончили заупокой)
← →
Elen © (2006-09-04 14:23) [24]
> inttostr(Edit1.Text)
StrToInt(Edit1.text)
← →
Elen © (2006-09-04 14:25) [25]
> vodvorezlaya
А ты когда нибудь контроллерами занимался или новичок в этом деле?
(заодно Делфи подучи inttostr(Edit1.Text) это уже перегрев на работе)
← →
han_malign © (2006-09-04 14:26) [26]
> У меня там другой протокол, но похоже у меня RK-512
- да по барабану какой протокол, кодирование потока редко менятся. Но тут есть два варианта, либо они целиком 8 байт double переворачивают, либо пословно(из описания непонятно)...function ntod(pw: PWord; fFullSwap: boolean): double;
var __pw: array[0..sizeof(Result)div 2 - 1]of word absolute Result;
i: integer;
begin
if(fFullSwap)then begin
for i:= Low(__pw) to High(__pw) do begin
__pw[High(__pw)-i]:= Swap(pw^);
inc(pw);
end;
end else begin
for i:= Low(__pw) to High(__pw) do begin
__pw[i]:= Swap(pw^);
inc(pw);
end;
end;
end;
- но это если предполагать что там гарантированно стандартный double...
← →
vodvorezlaya (2006-09-05 08:17) [27]
> это уже перегрев на работе
Так и есть.
> А ты когда нибудь контроллерами занимался или новичок в
> этом деле?
Каждый день симатик глаза мозолит, немного шарю в Step7.
← →
Elen © (2006-09-05 08:18) [28]
> vodvorezlaya
Сочувствую. Мне с ICPcon попроще. и стоит он дешевле
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.04 c