2015-09-23 7 views
4

У меня проблема с ПЛК (программируемый логический контроллер), который не обрабатывает денормализованные плавающие точки.Нормализовать с плавающей запятой

Вот несколько шестигранного представления чисел (денормализованный) Я получаю от контроллера на на противоположном стороне моего PLC: 0x00004180, 0x0000C180, 0x00006FA0

ли кто-нибудь будет так любезно, чтобы поделиться небольшим примером кода (C++/C# или аналогичный) о том, как побитовое нормализовать значение, подобное приведенному выше? Я не могу использовать какие-либо операции с плавающей запятой для чисел, поскольку они не распознаются в ПЛК, поэтому только операции HEX/BIN.

Прецизионность не является проблемой.

+0

Какой формат эти поплавки в? IEEE 754 с двойной точностью? –

+3

Денормализованные поплавки меньше, чем минимальные нормализованные поплавки, «нормализация» их будет означать нижнее значение до 0 или округлить до FLOAT_MIN. – hdl

+0

@Mark: IEEE 754, одинарная точность –

ответ

3

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

Денормализованные меньше 2^{- 126} и дробная часть не имеет неявный набор ведущих бит, поэтому в основном денормализованное число с плавающей точкой 0.mantissa * 2^{- 126}

Вы могли бы принести маску в int32_t и затем ваше значение с плавающей точкой, равное int_val * 2^{- 126 - 23} = int_val * 2^{- 149}. Число 23 связано с тем, что формат binary32 имеет 23 бита мантиссы. Конечно, вы сохранили бы целочисленное значение и значение экспоненты в разных переменных.

1

Если вы bitshifting с расширением знака, простой и внеофисный подход к смывать денормализованные числа к нулю следующим образом (где f является целым числом переосмысление числа с плавающей точкой):

int32_t x = f & 0x7F800000; // mask out sign and mantissa 
x += 0x7F700000; // overflows unless exponent is zero; MSB now indicates normalized 
x >> 31; // sign-extend the MSB to all bits 
f &= x; // flush denormals to zero 
Смежные вопросы