Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.09.24;
Скачать: CL | DM;

Вниз

Помогите с преобразованием типов данных   Найти похожие ветки 

 
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.
> pdf
> 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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.042 c
1-1155644817
DelphiLexx
2006-08-15 16:26
2006.09.24
Копировать и вставить несколько контролов


2-1157624743
VitV
2006-09-07 14:25
2006.09.24
Построение диаграммы


3-1153894912
ru_efim
2006-07-26 10:21
2006.09.24
Как использовать метод NextRecordSet компонента TADOStoredProc ?


15-1157041214
Sam Stone
2006-08-31 20:20
2006.09.24
TNSListner


15-1157516076
SergP
2006-09-06 08:14
2006.09.24
О переводе имен и фамилий.