Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Определение корректности переменной типа float


Автор: Ares4322 22.10.2011, 16:28
Доброго времени суток!
Есть самописная серверная программа. С клиентами этот сервер общается по самописному же бинарному протоколу. Разбор пришедших данных осуществляется самым простым образом - memcpy массива принятых байт в структуру с упакованными полями. Формат протокола подразумевает наличие в пакете данных полей с типом unsigned float. Так как float в языке С должен соответствовать стандарту IEEE, то бывают ситуации, когда приходят некорректные данные и в поле типа float лежат данные, не соответствующие этому формату. Каким образом можно определить, что в переменной типа float данные в битовом виде соответствуют (или не соответствуют) формату  IEEE и с ними можно работать как с переменной типа float?

Автор: Estranged 22.10.2011, 17:23
Цитата(Ares4322 @  22.10.2011,  16:28 Найти цитируемый пост)
unsigned float

Это как?! smile 

http://steve.hollasch.net/cgindex/coding/ieeefloat.html
http://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%BE%D0%B4%D0%B8%D0%BD%D0%B0%D1%80%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8
http://www.binaryconvert.com/convert_float.html
http://cant.ua.ac.be/old/ieeecc754.html

Проверить, что данные не меньше минимального и не больше максимального числа и не бесконечности.

Автор: Ares4322 23.10.2011, 21:21
Сорри, ошибся. float. так как определить корректность-то? я знаю, что есть стандарт. может подскажете какие-нибудь способы или библиотеки. найти ссылку на стандарт я и сам могу.

Автор: volatile 24.10.2011, 00:45
Цитата(Ares4322 @  23.10.2011,  21:21 Найти цитируемый пост)
как определить корректность-то?

Имхо, сама задача не верна.
С примерно таким-же успехом можно задасться вопросом, как определить корректность инта. Да никак!
Флоат правда не инт, у него есть несколько невозможных состояний, но это очень редкие случаи.
Можно поставить вопрос так: как определить невозможную или денормализованную комбинацию во флоате.
Это корректная задача, но не думаю что это то, что вам нужно.

Автор: Леопольд 24.10.2011, 12:51
Цитата(Ares4322 @  22.10.2011,  16:28 Найти цитируемый пост)
бывают ситуации, когда приходят некорректные данные и в поле типа float лежат данные, не соответствующие этому формату.
Что за ситуации?

Автор: borisbn 24.10.2011, 14:11
Код

// Возвращает true, если x = NaN или +-Inf
bool check_NaN_Inf( float x )
{
    unsigned int * iX = (unsigned int*)(&x);
    if ( ((*iX) & 0x7F800000) == 0x7F800000 )
    {
        return true;
    }
    return false;
}


Способ варварский, но работает smile

Автор: Ares4322 24.10.2011, 14:38
borisbn,  спасибо, попробую.
Хоть один человек вместо спама дело написал.

Автор: bsa 24.10.2011, 15:40
Цитата(Ares4322 @  24.10.2011,  15:38 Найти цитируемый пост)
Хоть один человек вместо спама дело написал. 

Тебе остальные не спам писали, а пытались объяснить, что эта задача не имеет смысла. Ну отловишь ты 0.0001% возможных ошибок. А дальше что? А если тебе придет вполне штатным образом NaN или Inf? Эта функция обозначит их ошибками. Уж лучше добавь контрольную сумму в пакет - надежность возрастет на несколько порядков. Если структура пакета фиксирована, то остается только логический контроль. Т.е. если тебе приходит текущая координата автомобиля, и на основании предыдущих вычислений ты установил, что скорость равна 20 м/с, то можно предположить, что через секунду координата изменится на 20 м. Если водитель нажал на газ, то она может измениться чуть сильнее. А если въехал в бетонный столб - то не измениться (но в этом случае, координата уже не так важна). Но она не может измениться на 5000 м. А уж тем более, уменьшиться (ну если только он не въехал во встречный камаз, груженый песком).

Автор: math64 24.10.2011, 20:38
Цитата(borisbn @  24.10.2011,  14:11 Найти цитируемый пост)
Способ варварский, но работает 

в math.h определён макрос isnan() - лучше пользоваться им

Автор: Ares4322 24.10.2011, 21:05
Проблема в том, что в протоколе есть CRC и оно корректно, так как отправитель упаковывает некорректные данные на своей стороне. Поэтому CRC не подойдет. А всякие эвристические методы анализа данных - это всегда куча допущений. Поэтому проще проверить float это или нет. И если нет, то не выдавать ошибку.
math64,  спасибо, посмотрю.

Автор: Estranged 24.10.2011, 22:40
http://msdn.microsoft.com/en-us/library/39s1cck2%28v=vs.80%29.aspx
Если не _FPCLASS_PN или не _FPCLASS_PN, то подозрительное число.
Еще http://msdn.microsoft.com/en-us/library/sb8es7a8%28v=vs.80%29.aspx.

Автор: bsa 25.10.2011, 10:27
Цитата(Ares4322 @  24.10.2011,  22:05 Найти цитируемый пост)
отправитель упаковывает некорректные данные на своей стороне

супер. Отправителя поправить нельзя? Может у него какой-то другой формат float? Как выглядят некорректные данные, т.е. как их ты сам отличаешь от корректных?

Автор: Ares4322 25.10.2011, 10:48
Формат float такой-же, как и у меня. Отличает их БД, потому что в запрос, где должен быть float кладется хз что. БД, соответственно, ругается. 
То есть парсер, по сути, у меня сейчас БД. Но это неправильно, хотя и просто. И хотелось бы парсер сделать на серверной стороне.

Автор: math64 25.10.2011, 11:07
Если БД нужен нормальный 0, а пришёл какой-то нестандарнтый вариант, можно сделать нормализацию:
Код

float x;
float zero = 0.0;
x = x + zero; // x + 0.0 компилятор может соптимизировать


Автор: bsa 25.10.2011, 11:50
Цитата(Ares4322 @  25.10.2011,  11:48 Найти цитируемый пост)
Отличает их БД, потому что в запрос, где должен быть float кладется хз что.

Кем и что кладется?

Автор: xvr 25.10.2011, 13:02
Цитата(Ares4322 @  25.10.2011,  10:48 Найти цитируемый пост)
Отличает их БД, потому что в запрос, где должен быть float кладется хз что.

А в БД этот float тоже в бинарном виде передается? Мне почему то кажется, что в текстовом  smile 
Кстати, и NaN и Inf - это валидные float значения (как это понимает IEEE).

Автор: Ares4322 25.10.2011, 15:12
xvr,  данные передаются в запрос именно в текстовом виде. float - это тип поля в БД

Автор: baldina 25.10.2011, 15:36
Цитата(Ares4322 @  25.10.2011,  15:12 Найти цитируемый пост)
xvr,  данные передаются в запрос именно в текстовом виде. float - это тип поля в БД 

ну так не морочьте людям голову, так и скажите: БД не нравится, когда Вы ей даете значение поля типа float в виде строки 'nan' или 'inf'.
Проверяйте при помощи isinf() и isnan(), как Вам посоветовал math64

Добавлено через 1 минуту
Цитата(Ares4322 @  22.10.2011,  16:28 Найти цитируемый пост)
 Каким образом можно определить, что в переменной типа float данные в битовом виде соответствуют (или не соответствуют) формату  IEEE и с ними можно работать как с переменной типа float? 

согласитесь, это совсем про другое вопрос  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)