Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.134.102.182] |
|
Сообщ.
#1
,
|
|
|
Всем хай! Сходу к делу!
Есть такая "система": Прикреплённая картинка
a, b, c, x - вещественные. Ок, допустим можно написать такую функцию (вот ее заголовок): double F ( const double a, const double b, const double c, const double x ); Для 1ой ветви такой вызов, например: F( 1, 2, 3, -5 ); - тут все ОК Для 2ой ветви такой: F( 1, 0, 5, 5 ); и вот уже ни хрена не ОК, т к будет деление на 0. В этом случае перетекаем в 3ю ветвь, что ли? Для 3ей ветви: F( 1, 0, 0, -5 ); опять деление на 0 Некорректная постанова, да, получается? Или здесь я чего-то не замечаю и "система" ВСЕГДА имеет смысл? |
Сообщ.
#2
,
|
|
|
Смотря что понимать под "корректностью постановки". Так, при c=0 и попадании в случай 3 можно считать, что F неопределена и всё корректно.
|
Сообщ.
#3
,
|
|
|
как я понял, вводят с клавиатуры a, b, c, x и нужно вывести на экран значение функции, т е функция типа всегда принимает допустимое значение из своей ОДЗ, я хз
а вообще это популярная задача (такого типа) и по сети гуляет много ее разновидностей, так по-разному ее лепят, но проверок деления на 0 не делают почти нигде все это странно, все это оч.странно... |
Сообщ.
#4
,
|
|
|
Ну и я б не делал. Задача ничего специального не требует, код насчитает то же, что должно получиться математически – бесконечность. Причём с правильным знаком. Зачем излишнюю инициативу проявлять?
Добавлено Ну или будет 0/0, что является неопределённостью, и код тоже вернёт NaN. И тут математически верный результат. |
Сообщ.
#5
,
|
|
|
Цитата Qraizer @ Ну и я б не делал. хорошо, вот данная "система" в заданном виде: double F( const double a, const double b, const double c, const double x ) { #define EPS 0.0001 double result; // 1 ветвь системы if ( ( x < 0 ) && ( b != 0 ) ) result = a * x * x + b; else // 2 ветвь системы if ( ( x > 0 ) && ( fabs( b ) <= EPS ) ) result = ( x - a ) / ( x - c ); // 3 ветвь системы else result = x / c; return result; } Вот тест для 2ой ветки, когда будет деление на 0: double a = 1.0; double b = 0.0; double c = 5.0; double x = 5.0; double result = F( a, b, c, x ); В итоге в переменную result заносится значение 1.#INF000 (там много нулей идет). Я так давно не делил на 0, что даже забыл, что прожка не крашится при этом, ну, ок) А вот отловить это значение НЕ удалось. Для проверки на NAN есть функция из заголовка <float.h>: if ( _isnan( result ) ) printf( "\n Getting NOT a number!" ); Для проверки с 1.#INF00 пишут, что есть функция isinf / _isinf, но нет ее ни в math.h, ни в float.h. Покурив мат.часть я так и не понял, ее ввели только в С99 или она где-то раньше была еще, причем во всех примерах ее юзают налево и направо, а у меня VS 2010 (исходник *.c) НЕ видит этой функции isinf... В общем вывод такой для себя сделал: функцию F можно оставить БЕЗ проверок деления на 0 (хотя это ооооооооооочень странно выглядит) и просто выпечатывать то, что получилось: норм.значение, NAN или этот +-1.#INF00(0). Но вроде NAN невозможно получить ни при каких входных a, b, c, x - хотя не уверен. В общем единственное, что хотелось бы еще понять, как проверить на 1.#INF00 в C89 (или C90, я так и не понял на 100%, какой комплятор вшит в студию по дефалту, но точно не С99) |
Сообщ.
#6
,
|
|
|
Сообщ.
#7
,
|
|
|
Цитата Qraizer @ Не работает? да уж, все отлично работает в твоем варианте, я балда даже не заметил, что ты раньше все мне написал, что да как) вот так сделал: // return 1 if isinf, else 0 int __cdecl Is_inf( const double x ) { #define EPS 0.00001 // x/2.0 - x дает -1.#INF000, ок, поэтому пробуем вариант Qraizer :) // if ( ( fabs( x/2.0 - x ) <= EPS ) && ( x + 2 == x ) ) // вариант Qraizer работает превосходно! Вот так то. if ( ( x/2.0 == x ) && ( x + 2 == x ) ) return 1; return 0; } после всего этого я даже не буду уточнять, почему дробные значения сравниваются между собой на прямую через "==", почему получаем -1.#INF000 и т.п., т к вопросов в 1000 раз больше, чем ответов. Пока работает, ну и слава б-гу)) Нашел еще много полезной инфы по поводу стандарта С99 и мат.нововведений. Такое чувство, что С99 улучшился в основном ТОЛЬКО из-за расширения <math.h> и добавления кучи новых макросов, констант, функций isnan, isinf, INFINITY, а в С89 вообще ни хрена в этом плане полезного не было (лишь 22 мат.функции) и вот хрен его знает, почему VS 2010 "видит" функцию _isnan, о которой кстати почти нет инфы, а есть только про isnan. В общем тема оч.нюансовая и надо с ней знакомиться потихоньку, я уже немножко познакомился, благодаря Qraizer кое-что стало понятно, пока хватит) Правда через неделю все это забудется, но, ладно, будем разбираться дальше... Qraizer, спасибо за проверку на isinf - там дичь какая-то, но работает превосходно...с др.стороны так и нужно проверять это isinf и по-другому никак вообще |
Сообщ.
#8
,
|
|
|
Цитата FasterHarder @ Потому что для "дробных значений" aka "нормализованное вещественное" всегда будет "не равно". Уравнение x/2 == x не имеет ненулевых решений. "Равно" возможно только для спец.форматов: нуля и бесконечности. после всего этого я даже не буду уточнять, почему дробные значения сравниваются между собой на прямую через "==" Добавлено P.S. Нуль тоже спец.формат, как ни странно. И это единственное "вещественное", для которого IEEE может гарантировать точность операций эквивалентности. |
Сообщ.
#9
,
|
|
|
Цитата Qraizer @ "нормализованное вещественное" кстати, в С99 что-то добавлено для обработки нормализованных вещественных Qraizer, спс за помощь |
Сообщ.
#10
,
|
|
|
Цитата FasterHarder @ Ну вот так работает преобразование inf в строку. Единичка впереди – дань традиции, т.к. в прошлой редакции IEEE помимо "обычных" спец.форматов были ещё всяко-разные псевдо-: -бесконечноности, -нечисла, -нули и -денормализованное, а также ненормализованные числа. Единичка впереди однозначно отделяла псевды от настоящих. В современном IEEE псевды упразднены, но совместимость всё ещё местами играет роль. Знак же определяет... хм, знак. Бесконечность – она знаковая. Правда, опять же, в прошлом IEEE определял две бесконечности: аффинная и проективная. Последняя не различала знак, ныне этот тип в IEEE упразднён. Ну а нулики в конце просто дополняют поле вывода до нужной ширины, в %f по умолчанию 6 знаков после запятой. почему получаем -1.#INF000 Добавлено Цитата FasterHarder @ x/2.0 - x должно дать NaN, если x бесконечность. Вычитание двух бесконечностей одного знака – это неопределённость. // x/2.0 - x дает -1.#INF000, ... |
Сообщ.
#11
,
|
|
|
Цитата Qraizer @ Или особенность работы процедуры конвертирования в строку. В нормализованный числах ведь первая единичка мантиссы опускается.Единичка впереди – дань традиции Ещё. Часто в IEEE-представлении при исчезновении порядка (число становится меньше минимально представимого нормализованного ненулевого) происходит переход к ненормализованному представлению. |
Сообщ.
#12
,
|
|
|
Денормализованному. Ненормализованный упразднён, как и всякие там псевды, и отличается тем, что он имеет порядок в валидном диапазоне вместо минимально представимого. Ненормализованный никогда не считался нормальным форматом (как минимум из-за потери точности представления) и в своё время допускался в связи с тогдашными ограничениями аппаратных реализаций IEEE, предполагалось, что им будут помогать программно нормализовывать этот спец.формат. Никакого полезного смысла в этом формате не было. Денормализованные в отличие от них полезны, т.к. позволяют плавно, посредством постепенной потери точности мантиссы, сводить очень малые значения к нулю, вместо того, чтобы обнулить сразу и резко. При этом такие значения всё равно обрабатываются корректно и выводятся в обычной форме.
Замечу, что все спец.форматы, кроме нуля, возможны только при явной старшей единице. Ныне таковым является только оригинальный long double, который 80-битный, он по-прежнему поддерживается FPU, но уже очень давно не имеет официального отражения на типы C/C++ (хотя Intel Compiler всё ещё имеет ключик командной строки для его активации) и всякие там SIMD с его SSExx. Но ты можешь быть прав, я не проверял, как ведут себя библиотеки при работе с ненормализованными числами, ибо сейчас уже тупо нет железа, на котором можно было бы проверить сие. |