Подробно о формате REAL в контроллерах Siemens

По просьбе наших посетителей, данный материал перенесен с сайта plc4good.org.ua, в связи с полной его потерей. Всё возражения принимаются через форму обратной связи.

plc4good.org.ua/view_post.php?id=165

Числа с плавающей точкой, на данный момент являются самыми часто используемыми.

 

real

В статье, приведены нетрадиционные способы работы с ними.

Введение

Тема чисел с плавающей точкой, оказалась неожиданно очень большой, поэтому в данном материале будут приведены только основные сведения. Для более подробного ознакомления придется изучать другие источники, в основном, конечно, сам стандарт IEEE 754.
В контроллерах фирмы Siemens пока используются только числа одинарной точности (single) размером 4 байта, что несколько сокращает данный обзор.

Начнем со стандарта, который описывает эти числа. Найти его можно на сайте разработчика IEEE.org и скачать для ознакомления 58 страниц pdf, заплатив всего лишь 89 американских рублей… Хм, сильный ход, учитывая, что они являются владельцами патента и вроде как заинтересованы в массовом распространении своих стандартов.

real

Тем не менее, найти его в интернете довольно легко.
уже не легко, ссылка и материал удален, по причине очень настойчивой просьбы правообладателя.

Теория

Число с плавающей точкой по стандарту IEEE754 выглядит так:

(-1) sign * b exponent * significand
где:
b = radix, 2 или 10 (в нашем случае 2)
s = знак (1 для отрицательных чисел)
significand = мантисса

real

Всего существует несколько видов чисел с плавающей точкой:
– Нормализованные (normal)
– Денормализованные (subnormal)
– -0 и +0 (отрицательный и положительный ноль)
– NaN (не числа)

real

 

Практика

Для начала выделим составляющие числа REAL стандарта IEEE754 (знак, порядок, мантисса)

 

FUNCTION_BLOCK  FB1
 
TITLE = ‘divide real’
//
// divide real number to part s * m * (2^-23) * (2 ^ e).
//
AUTHOR: dda

VAR_INPUT
        in: REAL ,       
        _in AT in : STRUCT
        _dw: DWORD,
        END_STRUCT,   
       
END_VAR

VAR_OUTPUT
s: INT,         // sign
e: INT,         // order
m: DINT,        // mantisa
END_VAR
 
        IF DWORD_TO_BOOL(SHR(in:=_in._dw,n:=31)) THEN s:=-1, ELSE s:=1, END_IF,
       
        e:=DWORD_TO_INT(SHR(in:=_in._dw,n:=23) AND DW#16#FF),
       
        IF e=0 THEN m:=DWORD_TO_DINT(SHL(in:=(_in._dw AND DW#16#7fffff),n:=1)), ELSE m:=DWORD_TO_DINT((_in._dw AND DW#16#7fffff) OR  DW#16#800000),   END_IF,
             
        e:=e127,
 
END_FUNCTION_BLOCK
 
 

Проверяем:

real
Работает!

Пример работы с полем знака
real
Абсолютное значение числа
Инверсия знака числа

Пример работы с полем порядка

real
Умножение на два

real
Деление на два

Пример работы с полем мантиссы

Что-то сделать с мантиссой сложно, да, каждый бит мантиссы имеет числовой вес, но он зависит от значения поля степени. Поэтому просто добавим константу к текущему значению, для демонстрации расчета.

Весовые значения каждого бита в мантиссе

Добавляем константу +2.0

В данном примере добавляется к исходному числу бит 22, весовой коэффициент которого 0.5, порядок исходного числа 2, значит, на самом деле к исходному числу добавляется 0.5*22=2.0

Сравнение

Есть еще один вариант работы с числами с плавающей точкой, нетрадиционными методами, а именно – сравнение. Это можно проделать, основываясь на том факте, что числа, кодированные по стандарту IEEE754 – корректно упорядочены, если их рассматривать как знаковые целые числа.
Сравнение можно существенно упростить, если считать, что величина -0.0 меньше +0.0 (но это не соответствует стандарту IEEE754). Также эти сравнения не работают с неупорядоченными числами типа NaN.

 

FUNCTION_BLOCK FB100
VAR_INPUT
a: REAL,
_a AT a: STRUCT
      dw: DINT,
END_STRUCT,
b: REAL,
_b AT b: STRUCT
      dw: DINT,
      END_STRUCT,
END_VAR

VAR_OUTPUT
a_less_b: BOOL,
END_VAR

IF      ((_a.dw&gt,=0) AND (_a.dw&lt,_b.dw))
        OR
((_a.dw&lt,0) AND (_a.dw&gt,_b.dw))
THEN
a_less_b:=true,
ELSE
a_less_b:=false,
END_IF,

END_FUNCTION_BLOCK

Советы

Учитывая то, что формат чисел с плавающей точкой, содержит определенные недостатки, при работе с ними необходимо учитывать следующие нюансы:

Стараться работать с числами одних порядков

Здесь погрешность относительно результата составила 800 процентов,
если использовать результат в последующих вычислениях, с числами порядка 101 – будут проблемы.

Сравнивать на равенство правильно, иначе два числа, которые должны быть одинаковы по вычислениям, в результате накапливания погрешности могут не дать необходимого результата.

real

Где eps допустимая погрешность, обычно максимальное число, которое при добавлении к единице, дает в результате опять единицу.

Посчитаем это значение для контроллеров Siemens.

real
Значение совпадает с заявленным в стандарте.

Учитывать возможность накопления погрешности при многочисленных вычислениях,
например, если мы возьмем миллион случайных чисел от 0 до 1 и сложим их, мы получим один результат, если мы сначала отсортируем эти же числа и сложим снова, мы получим другой результат, если отсортируем исходный набор в другом порядке и сложим – получим третий результат.

Источники

Забавный материал в духе – Как IEEE754 уничтожит человечество? – yur.ru/science/computer/IEEE754.htm
Хорошее описание с примерами – softelectro.ru/ieee754.html
а также книга ‘Hacker’s Delight’ Henry S. Warren, Jr. 2002 год. Charter 15

Еще хотелось бы в данной статье оценить быстродействие приведенных примеров, но, к сожалению, в данный момент нет доступа к реальному контроллеру, а результаты на симуляторе не внушают доверия. Поэтому статья обновится чуть позже.

Комментарии к материалу

Добавлен: Семён Дата: 2013-04-24

Для S7-1500 ввели формат длинный 64-битный L Real, который решит глюки короткого 32-битного Реала
i053.radikal.ru/1304/0f/6301936a99fe.jpg

Добавлен: Алексей Дата: 2013-12-21

По поводу результата на симуляторе – это вы зря. Он работает на базе WinLC – что есть полный аналог s7-400.

Добавлен: komatic Дата: 2013-12-21

возможно и так, но слова ‘полный аналог’ и ‘есть нюансы’ для меня синонимы 🙂

Добавлен: WarLex Дата: 2014-05-13

почему ограничение формата REAL 3.402823466e+38, Пробовал поставить единицы во всех разрядах ‘e’ не получилось(((

0 0 голоса

Оцените статью!

guest
0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии