SIEMENS, DF&PD

Предыдущее посещение: Вт июл 05, 2016 3:16 Текущее время: Вт июл 05, 2016 3:16

Часовой пояс: UTC + 3 часа




 [ Сообщений: 8 ] 
Автор Сообщение
 Заголовок сообщения: Помогите с передачей Real через S7ProSim
СообщениеДобавлено: Чт авг 28, 2014 18:53 
Не в сети
Новый писатель

Зарегистрирован: Чт дек 27, 2012 10:38
Сообщения: 10
Часа полтора не могу понять как в C# преобразовать полученное из CPU значение Real в нормальный вид.

Собственно код:
ps.ReadDataBlockValue(750,28,0,PointDataTypeConstants.S7_DoubleWord, ref pData);

Тип pData object все как положено.
Целые числа передаются на ура, проблем нет.

Но вот с Real проблема...
В SimCPU записано в DB750.DBD28 значение Real 10.5(или 1.050000e+001).
В программе(C#) получаю - Int32=1093140480 или если преобразую во float =1.09314E+09.
Значение Int32=1093140480 в CPU вижу при отображении 10.5 в формате decimal.

Я так понимаю что битовая последовательность из SimCPU в C# передается верно. Проблема только в отображении Real в C#. Может необходимо преобразование или тип какой. Кто сталкивался отзовитесь.
Буду рад любым мыслям.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Чт авг 28, 2014 19:29 
Не в сети
Известный Писатель

Зарегистрирован: Пт июн 30, 2006 15:53
Сообщения: 265
Откуда: Краснодар
Разбей реал побайтно и преобразуй из
1 2 3 4
в
3 4 1 2


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Чт авг 28, 2014 19:36 
Не в сети
Это точно не человек

Зарегистрирован: Чт фев 16, 2006 12:27
Сообщения: 7509
Откуда: Украина
1093140480 в десятичном виде - это 41280000 в шестнадцатиричном. Число 10.5 в соответствии с IEEE 754 тоже выглядит как 41280000 в шестнадцатиричном представлении. Проблема в порядке байт. Попробуйте "перевернуть", т.е. в двойном слове, представляющем число с плавающей точкой, поменять местами младшее слово со старшим, а затем в каждом слове - младший байт с старшим.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт авг 29, 2014 13:44 
Не в сети
Новый писатель

Зарегистрирован: Чт дек 27, 2012 10:38
Сообщения: 10
Попробовал вышеописанные советы... К сожалению дело не в этом... Есть еще мысли?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с передачей Real через S7ProSim
СообщениеДобавлено: Пт авг 29, 2014 14:45 
Не в сети
Это точно не человек

Зарегистрирован: Чт фев 16, 2006 12:27
Сообщения: 7509
Откуда: Украина
Den&Ko писал(а):
В программе(C#) получаю - Int32=1093140480 или если преобразую во float =1.09314E+09.

Кажется, дело не в порядке байт. По всей вероятности, Вы не в курсе, как кодируются числа в формате float, т.е. число с плавающей точкой размером 4 байта. Поиск по ключевой фразе "IEEE 754" в помощь. Если интерпретировать битовую последовательность как Int32, то получается десятичное число 1093140480 (0x41280000). А вот преобразование в формат float лишнее. Естественно, получится 1.09314E+09, ещё и точность потерялась, хотя в данном случае не должна бы. Достаточно просто интерпретировать битовую последовательность как float и всё. Как я писал выше, 10.5 также представляется именно как 0x41280000.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с передачей Real через S7ProSim
СообщениеДобавлено: Пт авг 29, 2014 20:10 
Не в сети
Новый писатель

Зарегистрирован: Чт дек 27, 2012 10:38
Сообщения: 10
Eugene1974 писал(а):
Кажется, дело не в порядке байт. По всей вероятности, Вы не в курсе, как кодируются числа в формате float, т.е. число с плавающей точкой размером 4 байта. Поиск по ключевой фразе "IEEE 754" в помощь. Если интерпретировать битовую последовательность как Int32, то получается десятичное число 1093140480 (0x41280000). А вот преобразование в формат float лишнее. Естественно, получится 1.09314E+09, ещё и точность потерялась, хотя в данном случае не должна бы. Достаточно просто интерпретировать битовую последовательность как float и всё. Как я писал выше, 10.5 также представляется именно как 0x41280000.


Ну я собственно в самом начале это и имел ввиду...


Вот тут-то и загвоздка. Получить данные нужно в pData типа object, больше никак... Чтобы
Eugene1974 писал(а):
... просто интерпретировать битовую последовательность как float и всё.

pData приходится перегнать в string(текстовый тип) и только потом float.Parse(string) перегнать во float.
Если сделать так pData.ToString(), то тип будет Int32.(проверено)

Вообще пробовал по разному, результат такой же.

Курю статьи формированию типа float, задаю последовательности битов с известным результатом, но получаю чушь.
Вы правы... я не знаю как кодируются числа в формате float - теория которую я читаю не сходится с опытом. Думаю все это от не глубокого понимания C#.

Сдаваться пока не собираюсь. Есть идеи ... делитесь, буду рад!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Сб авг 30, 2014 17:09 
Не в сети
Начинающий писатель

Зарегистрирован: Ср сен 20, 2006 15:54
Сообщения: 75
Откуда: Germany
Я когда то тоже столкнулся с этой проблемой и написал такую функцию на VB.NET которая ехтрагирует мантиссу и порядок из 32-битов

Код:
'Integer (32 bits) to Single (REAL)
    Private Function DwordToSingle(ByVal d As Integer) As Single
        Dim e As Integer
        Dim m As Integer
        Dim c As Boolean = False
        Dim s As Single

        e = (d And &H7F800000) / &H800000
        m = d And &H7FFFFF
        If d < 0 Then c = True
        s = ((-1) ^ c) * (1 + m / 8388608) * 2 ^ (e - 127)
        If d = 0 Then s = 0

        Return s

    End Function

Сожалею что я тогда код не откомментировал, мне казалось он в комментах не нуждается :(


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с передачей Real через S7ProSim
СообщениеДобавлено: Сб авг 30, 2014 21:11 
Не в сети
Это точно не человек

Зарегистрирован: Чт фев 16, 2006 12:27
Сообщения: 7509
Откуда: Украина
Den&Ko писал(а):
Вот тут-то и загвоздка. Получить данные нужно в pData типа object, больше никак... Чтобы
Eugene1974 писал(а):
... просто интерпретировать битовую последовательность как float и всё.

pData приходится перегнать в string(текстовый тип) и только потом float.Parse(string) перегнать во float.
Если сделать так pData.ToString(), то тип будет Int32.(проверено)

Вообще пробовал по разному, результат такой же.

Вы пошли сложным, а главное - неправильным путём. Повторяю, данные надо не преобразовывать, но правильно интерпретировать.

Вот код на обычном ANSI C:
Код:
union
{
   float floatVal;
   int intVal;
} data;
// Суть объединения (union) в том, что переменные floatVal и intVal занимают одну и ту же область памяти - 4 байта

// Задаём данные как int
data.intVal = 0x41280000;
// Выводим те же данные как float
printf("%f\r\n", data.floatVal);
Угадайте с трёх раз, что выводит printf?

Вот ещё код, показывающий, как можно правильно интерпретировать данные:
Код:
int value;

value = 0x41280000;
printf("%f\r\n", *(float *)&value);
И снова printf выводит 10.500000.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
 [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения

Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group