ООООО!!! ПАСИБО! Занесу себе в заметки, чтобы не забыть.
А как его склеить правильно? В смысле, я пойму как склеить два байта в WORD или четыре байта в... а во что их клеить? Сначала в DWORD, а потом его в REAL? Знак у FLOAT не потеряется при этом?
Вид для печати
Валенок не везде, не путать с ПЛК63 (если не ошибся) :)
Cs-Cs REAL и FLOAT суть одного и того же. главное чтобы байты шли правильно. в данном случае по стандарту IEEE 754.
Ещё раз спрошу - поучусь.
А точно? А то я как-то WORD в REAL переводил - и у меня при отрицательных температурах с AI были значения фиг какие огромные. А дело было в знаковом и беззнаковом типе.
Поэтому я и хочу ещё раз спросить, как из 4х байт правильно собрать REAL. Чтобы точно не ошибиться.
Можно встречный вопрос - зачем Вам REAL с модуля? Ну нет смысла брать более 1..2 знаков после запятой, они не значащие. Порядок (степень над 10) тоже не сильно меняется. Поэтому - INT и переводим в REAL, если надо.
Код разбора ответа от модуля 8АС
Читаем с адреса 280 32 регистра одним запросом
FOR ix:=0 TO 7 DO
Arr_mva1 [ix].Status:= BYTE_TO_WORD(Buffer[ix*2+1])(* Статус 1,3,5,7,9,11,13,15 байты*);
ptr_byte :=ADR(Arr_mva1[ix].r_Value);
FOR y:=0 TO 3 DO
ptr_byte^:=Buffer[(ix*3+8)*2+3-y]; (* Значение REAL разбираем начиная с последнего байта 19,25,31,37,43,49,55,61 *)
ptr_byte :=ptr_byte+1;
END_FOR
END_FOR
ASo Потому что когда я делал по схеме WORD_TO_REAL(Value) / EXPT(10, WORD_TO_REAL(DigPoint)) - меня отругали и сказали что надо юзать FLOAT вместо этой фигни =)
А Float я чего-то боюсь и не понимаю... а ща, раз тему затронули, есть шанс спросить как правильно.
Итого, мои вопросы:
1. Чтобы не терять знак при преобразованиях, мне значение регистра, которое WORD, надо преобразовывать в INT, который знаковый?
Верно?
2. Если я хочу собрать REAL (то есть FLOAT), то как делать так, чтобы не потерялся знак?
Я не понимаю пока что. Вот есть у меня 4 байта. Я могу из них собрать DWORD побитно, как подсказал Валенок.
И чего мне с этим DWORD делать, в котором мои 4 байта будут?
SysMemCpy ему в REAL что ли делать?
Или просто написать DWORD_TO_REAL?
Тут я туплю, и мне надо не код с магическими числами как у Sergey66 (так учили писать в совковых школах, где все индексы i и j, и ни хера не ясно что то всё значит), а понять типы данных и то, как они собираются из байт.
1) Просто объявить как INT, этого достаточно
2) DWORD вообще не нужен, из 4 байт сразу собираешь REAL, знак не потеряется
Я раньше делал так
W[0]:=byIn1 ; (* четыре BYTE_а, из которых собираем rOut REAL *)
W[1]:=byIn2 ;
W[2]:=byIn3 ;
W[3]:=byIn4 ;
ptr_In :=ADR(W);
ptr_Out := ADR( rOut);
ptr_Out^[ 0 ] :=ptr_In^[ 0 ] ; (* при желании можно BYTEы поменять местами*)
ptr_Out^[ 1 ] :=ptr_In^ [ 1 ] ;
ptr_Out^[ 2 ] :=ptr_In^[ 2 ] ;
ptr_Out^[ 3 ] :=ptr_In^ [ 3 ] ;
Потом Валенок научил как считывать 4 строками все данные из МВА8, кстати всё было выложено в теме Для новичков, которую удалили(((
Уже похер... может под осень я напишу пост у себя на блоге, и тут на форуме буду ссылку давать.
Чтобы картинки были, скриншоты и понятный код.
Валенок Вот любишь ты придиратьс =)) ПобАЙТного, побайтного - думал о другом (побитовый сдвиг, чтобы DWORD клеить), вот и написал про биты.
Ага, вот поэтому я жесткий противник техноблогосферы- сам толком не разобрался в азах, а туда-же, бложок, понятный код, картиночки пальчиком...
Функция Adr() возвращает адрес первого байта любой переменной, размер и тип не важен! Ты сам должен понимать сколько байт в требуемой переменной. И теперь мы имеем, при разборе буфера ответа некое количество байт и, зная где эти байты в массиве можно "Напихать" эти байты в переменную, адрес первого байта которой мы имеем как угодно путем непосредственной адресации по указателю, см. выше код, что не понятного?
П.С Никогда и ни при каких условиях не использовать тип WORD(DWORD) для числовых переменных!!! Этому в школах советских учили!
Ну вот, WORD нельзя использовать)))
Провёл эксперимент, считал все параметры МВА8, двумя стрингами по 24 регистра в виде массивов WORD, склеил [5] и [4] WORD и получил REAL , который соответствует значению REAL Input из 4 и 5 регистров считанному напрямую. Куда уж проще для новичков))) А если не склеивать, то можно просто целочисленные взять, разделить на 10.0 и получить те же REAL с одним знаком))
module1_1 AT %IB11.1.0.0 : ARRAY[0..23] OF WORD ;
module1_2 AT %IB11.1.1.0 : ARRAY[0..23] OF WORD ; Вложение 55804