|
Как определить что float имеет не цифровое значение (NaN) |
|
|
|
 |
Ответов
(1 - 7)
|
Mar 13 2006, 12:55
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 14-01-06
Пользователь №: 13 160

|
Цитата(Vic1 @ Mar 13 2006, 16:54)  Можно так попробовать if ((*(unsigned long *)(&my_float)) == 0xffffffffL)
а 0x7fffffff - это тоже спец. значение, не float, поэтому в чем то компилер прав. Могу поискать описание этих спец.значений. Пробовал и так. В этом случае компилятор работает только с указателем на переменную, без ее непосредственного извлечения из eeprom, т.е. без вызова функции __eeget32_16. Если только делать это через промежуточную переменную в ОЗУ, но при десятках переменных в разных частях программы получается не очень красиво...
Сообщение отредактировал LeshaL - Mar 13 2006, 12:57
|
|
|
|
|
Mar 13 2006, 13:31
|

Частый гость
 
Группа: Свой
Сообщений: 112
Регистрация: 15-10-05
Из: Томск
Пользователь №: 9 680

|
Цитата(LeshaL @ Mar 13 2006, 17:03)  В __eeprom обьявлена переменная типа float. Как с минимальными затратами определить, что эта переменная имеет нечисловой формат (когда по адресу хранения float появляется значение 0xFFFFFFFF) чтобы привести ее в какое-нибудь начальное значение числового формата? Операции сравнения не работают. Если я пытаюсь определить нечисловой формат так: if(my_float==0.NaN), то, судя по ассемблерному тексту, my_float сравнивается не с 0xFFFFFFFF, a c 0x7FFFFFFF. Если сравниваю так: if(my_float==-0.NaN), то ничего не меняется... я делал так (в IAR 3.20): Код static char is_nan(const float *F) { return ((((unsigned char*)F)[2] & 0x80)==0x80) && ((((unsigned char*)F)[3] & 0x7F)==0x7F); } Этой ф-ии передаю указатель на float в RAM. Но эта ф-я зависит от порядка байт во float, этот вариант для IAR320 для AVR. Измени её под свои требования.
|
|
|
|
|
Mar 13 2006, 15:03
|
Частый гость
 
Группа: Свой
Сообщений: 166
Регистрация: 14-01-06
Пользователь №: 13 160

|
Цитата(starter48 @ Mar 13 2006, 18:31)  Цитата(LeshaL @ Mar 13 2006, 17:03)  В __eeprom обьявлена переменная типа float. Как с минимальными затратами определить, что эта переменная имеет нечисловой формат (когда по адресу хранения float появляется значение 0xFFFFFFFF) чтобы привести ее в какое-нибудь начальное значение числового формата? Операции сравнения не работают. Если я пытаюсь определить нечисловой формат так: if(my_float==0.NaN), то, судя по ассемблерному тексту, my_float сравнивается не с 0xFFFFFFFF, a c 0x7FFFFFFF. Если сравниваю так: if(my_float==-0.NaN), то ничего не меняется...
я делал так (в IAR 3.20): Код static char is_nan(const float *F) { return ((((unsigned char*)F)[2] & 0x80)==0x80) && ((((unsigned char*)F)[3] & 0x7F)==0x7F); } Этой ф-ии передаю указатель на float в RAM. Но эта ф-я зависит от порядка байт во float, этот вариант для IAR320 для AVR. Измени её под свои требования. В том то и дело, что передается указатель на float в RAM, а мне нужно проверить float во внутреннем eeprom. Каждый раз организовывать промежуточную переменную типа float только лишь для проверки валидности данных типа float в eeprom в разных кусках программы как-то коряво. Неужели нет более простого пути? Красиво работает if(my_float==0.NaN), но проверяет только на 0x7FFFFFFF, а в eeprom, сами понимаете, чаще может быть значение 0xFFFFFFFF.
|
|
|
|
|
Mar 13 2006, 16:59
|

Частый гость
 
Группа: Свой
Сообщений: 112
Регистрация: 15-10-05
Из: Томск
Пользователь №: 9 680

|
Цитата(LeshaL @ Mar 13 2006, 21:03)  Цитата(starter48 @ Mar 13 2006, 18:31)  я делал так (в IAR 3.20): Код static char is_nan(const float *F) { return ((((unsigned char*)F)[2] & 0x80)==0x80) && ((((unsigned char*)F)[3] & 0x7F)==0x7F); } Этой ф-ии передаю указатель на float в RAM. Но эта ф-я зависит от порядка байт во float, этот вариант для IAR320 для AVR. Измени её под свои требования. В том то и дело, что передается указатель на float в RAM, а мне нужно проверить float во внутреннем eeprom. Каждый раз организовывать промежуточную переменную типа float только лишь для проверки валидности данных типа float в eeprom в разных кусках программы как-то коряво. Неужели нет более простого пути? Я тебе дал идею как распознать NaN. Переделай эту ф-ю для работаы с EEPROM. Создавать отдельную переменную для этого совсем не обязательно. Можешь использовать указатель на float в eeprom. Пример (на железе не проверял): Код static unsigned char readEEPROM(unsigned char __eeprom *addr) { while(EECR&(1<<EEWE));//wait for EEWE -> 0 EEAR=(unsigned short)addr; EECR|=(1<<EERE);//master read EEAR=0;//to prevent EEPROM corruption return EEDR; }
static char is_nan(const float __eeprom *F) { return ((readEEPROM((unsigned char __eeprom*)F + 2) & 0x80)==0x80) && ((readEEPROM((unsigned char __eeprom*)F + 3) & 0x7F)==0x7F); } Цитата(LeshaL @ Mar 13 2006, 21:03)  Красиво работает if(my_float==0.NaN), но проверяет только на 0x7FFFFFFF, а в eeprom, сами понимаете, чаще может быть значение 0xFFFFFFFF. Это не корректно, т.к. NaN - это не только 0x7FFFFFFF. Т.е. тестировать на NaN через сравнение с константой некорректно.
|
|
|
|
|
Mar 14 2006, 06:14
|

инженер
   
Группа: Свой
Сообщений: 520
Регистрация: 19-09-05
Из: Самара
Пользователь №: 8 701

|
Цитата Цитата Красиво работает if(my_float==0.NaN), но проверяет только на 0x7FFFFFFF, а в eeprom, сами понимаете, чаще может быть значение 0xFFFFFFFF. Это не корректно, т.к. NaN - это не только 0x7FFFFFFF. Т.е. тестировать на NaN через сравнение с константой некорректно. Некорректность еще и в том, что результат операции сравнения float-оператора с НЕ-числом (это Ваша спец. константа) не дает правильного результата (для этого, т.е. грамотного управления вычислениями эти спец.константы и были введены в соотв. стандарт IEEE). Подробнее все в стандарте и можно посмотреть. Еще один посыл. Так как сравнение float-чисел выполняется с помощью специальной библиотечной функции, то и сравнение float c NaN необходимо делать аналогично - т.е. с помощью своей функции. Starter48 прав! Можно и на асме эту функцию написать, если захотите большей эффективности. З.Ы.: а NaN все-таки лучше не допускать в своих алгоритмах, эти константы были введены в стандарт для отладки программ, реализующих численные алгоритмы.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|