Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.
> 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.06 c
1-1155211730
Igor_thief
2006-08-10 16:08
2006.09.24
Работа с браузером


15-1157172791
tButton
2006-09-02 08:53
2006.09.24
поймал момент)


15-1157461067
memo
2006-09-05 16:57
2006.09.24
Разница дат....


15-1157356316
ANB
2006-09-04 11:51
2006.09.24
Понедельничная задачка (Оракл)


15-1157000425
begin...end
2006-08-31 09:00
2006.09.24
31 августа. С Днём рождения!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский