MrYuran 29 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба Сейчас встретил в программе кусок sprintf(str, "%f", fCNa); if(isalpha(str[1]))fCNa = 0; Я так подозреваю, что это проверка fCNa на допустимость (или как там по-русски сказать) Если это так, то решение, по-моему, слишком избыточное, учитывая что *printf() нигде больше не используется Какие могут быть другие способы, менее затратные? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 11 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба Какие могут быть другие способы, менее затратные?Если это - IEEE754, то "нечисла" (положительная и отрицательная бесконечность, нечисло, неопределённость) имеют в порядке (двоичное представление) все единицы. "Нормальные" числа в порядке содержат по крайней мере один нолик. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ashr 0 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба Какие могут быть другие способы, менее затратные? Я пользуюсь таким кодом: //****************************************************************************** // MISC_CPP // DESCRIPTION: // Различного рода вспомагательные функции. // // //****************************************************************************** //------------------------------------------------------------------------------ // T Y P E S and D E F I N I T I O N S //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // Константa NaN. const float NaN = 0.0/0.0; //============================================================================== // I M P L E M E N T A T I O N //============================================================================== //------------------------------------------------------------------------------ // Проверка значения float на число. bool is_nan(float val) { uint32 *pval = reinterpret_cast<uint32*>(&val); bool result = ((*pval & 0x7F800000) == 0x7F800000) && ((*pval & 0x007FFFFF) != 0x00000000); return result; } //------------------------------------------------------------------------------ // Проверка значения float на бесконечность. bool is_inf(float val) { uint32 *pval = reinterpret_cast<uint32*>(&val); bool result = ((*pval & 0x7F800000) == 0x7F800000) && ((*pval & 0x007FFFFF) == 0x00000000); return result; } //------------------------------------------------------------------------------ // Проверка значения float на корректность. Не Nan и не Inf. bool is_correct_float(float val) { return !(is_nan(val)||is_inf(val)); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 29 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба Я пользуюсь таким кодом: ... uint32 *pval = reinterpret_cast<uint32*>(&val); ... Спасибо, а вот это reinterpret_cast<uint32*> - на каком языке написано? я так подозреваю, на си это что-то типа (uint32*)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vik0 0 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба reinterpret_cast<uint32*> - на каком языке написано? я так подозреваю, на си это что-то типа (uint32*)? C++ Правильно подозреваете. ... Все уже придумано до нас :) #include <limits> // Проверка значения float на корректность. Не Nan и не Inf. bool is_correct_float(float val) { return val != std::numeric_limits<float>::signaling_NaN() && abs(val) != std::numeric_limits<float>::infinity(); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба Все уже придумано до нас :)Действительно, придумано.#include <math.h> // Проверка значения float на корректность. bool is_correct_float(float val) { return !isnan(val); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vik0 0 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба А как быть с +/-INF ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 29 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба В общем, всем спасибо, сделал misc.c как у shreсk'a, только на си. Результат - минус 4 кило из сегмента code и увеличение запаса оперативки Так вот живёшь-живешь, и вдруг - бац, оказывается, float принято на пределы проверять... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 3 февраля, 2009 Опубликовано 3 февраля, 2009 (изменено) · Жалоба А как быть с +/-INF ?Откровенно говоря не силен в плавающей точке, но логика подсказывает, что inf - это тоже not a number, и, значит, должен отсекаться по isnan(). Лезть в стандарт? Да, полез: это разные классы чисел. Надо использовать isfinite(): The isfinite macro determines whether its argument has a finite value (zero, subnormal, or normal, and not infinite or NaN). В общем, всем спасибо, сделал misc.c как у shreсk'a, только на си.Ошибочное решение. Представление плавающей точки - компиляторо- и процессорозависимо. Вы закладываететсь на конкретную реализацию, теряя портабельность. Разработчики компиляторов предоставляют стандартные макросы для этих операций - isnan() isinf() и кучу других. Если вас не устраивает их встраивание - сделайте обертки, но не закладывайтесь на конкретное представление чисел компилятором. Изменено 3 февраля, 2009 пользователем Сергей Борщ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба По-моему, правильно будет использовать isfinite(): The isfinite macro determines whether its argument has a finite value (zero, subnormal, or normal, and not infinite or NaN). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба По-моему, правильно будет использовать isfinite():Говорят, у дураков мысли сходятся... Но у умных чаще! :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vik0 0 3 февраля, 2009 Опубликовано 3 февраля, 2009 · Жалоба inf - это тоже not a number, и, значит, должен отсекаться по isnan(). Беглая проверка показала что MSVC++2008 так не считает. :unsure: Лезть в стандарт? Гляньте, если не затруднит. Хочется прояснить для себя этот вопрос. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ashr 0 4 февраля, 2009 Опубликовано 4 февраля, 2009 · Жалоба Ошибочное решение. Представление плавающей точки - компиляторо- и процессорозависимо. Вы закладываететсь на конкретную реализацию, теряя портабельность. Разработчики компиляторов предоставляют стандартные макросы для этих операций - isnan() isinf() и кучу других. Если вас не устраивает их встраивание - сделайте обертки, но не закладывайтесь на конкретное представление чисел компилятором. Полностью поддерживаю. Но... 1. Не у всех компиляторов стандартная библиотека содержит указанные функции, например, в IARMSP342 я их не нашел. 2. Если документация к компилятору утверждает, что он поддерживает для float стандарт IEEE 754, то, рискну предположить, что приведенный мной код не компиляторо- и не процессорозависимый. 3. Человеку нужно решение на С. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 11 4 февраля, 2009 Опубликовано 4 февраля, 2009 · Жалоба ... поддерживает для float стандарт IEEE 754, то, рискну предположить, что приведенный мной код не компиляторо- и не процессорозависимый.В Вашем коде есть одно "тёмное" место - приведение указателя на float к указателю на uint32. Правильность работы Вашего кода будет определятся - как транслятор располагает в памяти байты целых и вещественных чисел. Если - в используемом трансляторе нет стандартной функции определения "нечисла", то, имхо, с этим "тёмным" местом кода можно смириться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 4 февраля, 2009 Опубликовано 4 февраля, 2009 · Жалоба 1. Не у всех компиляторов стандартная библиотека содержит указанные функции, например, в IARMSP342 я их не нашел.Тут возразить нечего... Разве что можно предложить дать этим функциям стандартные названия, чтобы при компиляции компилятором, который имеет такие функции, получить ошибку и заменить их на библиотечные.2. Если документация к компилятору утверждает, что он поддерживает для float стандарт IEEE 754, то, рискну предположить, что приведенный мной код не компиляторо- и не процессорозависимый.А как же большие и маленькие индейцы? Затык именно в попытке обращаться к участку памяти как к длинному целому. К тому же, в зависимости от реализации компилятора, и float и double могут иметь непредсказуемое число бит.3. Человеку нужно решение на С.Вызов описанного в стандарте языка макроса стандартной библиотеки - самое что ни на есть "решение на С". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться