Sochin
Злой модератор
Декан
Карма: +108/-6
Offline
Пол:
Сообщений: 1518
|
|
« Ответ #20 : Июль 24, 2007, 10:58:27 » |
|
Поставил Билдер...Как-то он не по понятиям с исключениями работает... ))) Ушел читать стандарт С++. )))
|
|
|
Записан
|
Говорят, когда компьютер сгорает, перед взором микропроцессора за долю секунды проносятся все операции, которые он когда-либо совершил... 壯鎭
|
|
|
Sochin
Злой модератор
Декан
Карма: +108/-6
Offline
Пол:
Сообщений: 1518
|
|
« Ответ #21 : Июль 24, 2007, 06:55:48 » |
|
Итак, по результатам сегодняшнего мини-исследования можно констатитровать: 1) В консольном не-VCL проекте на Билдере блок не реагирует на исключения при делении на ноль, что противоречит стандарту С++. Подозреваю, что это связано с реализацией VCL-класса исключения EDivByZero еще на объектном Паскале в Дельфи, откуда она была импортирована в Билдер. Соотвественно, в коде int a = 10, b =0; try { double dd = a/b; } catch(...) { // }
исключение при делении не будет перехвачено и обработано, что приведет к аварийному завершению приложения. Так что в этом случае вопросы не ко мне, а к производителю компилятора. 2) Функция sqrt, будучи описанной и реализованной еще в библиотеке языке С, при ошибках в аргументе, связанных с областью определения функции не вызывает исключений. Соответственно, обработка подобных ошибок осуществляется не через механизм исключений, а через глобальную С-переменную errno. Учитывая эти находки был написан новый мего-код на стандартном C++: #include <vcl.h> // Только для Билдера, что связано с особенностями реализации классов-исключений.
#include<math> #include<errno> #include <algorithm> #include <set> #include <iostream>
using namespace std;
//--------------------------------------------------------------------------- void Err() { set<int, less<int> > errors, current, result;
insert_iterator<set<int, less<int> > > res_ins(result, result.begin());
errors.insert(EDOM); current.insert(errno);
set_intersection(errors.begin(), errors.end(), current.begin(), current.end(), res_ins);
while(result.empty()) return;
errno = 0; throw 10; } //--------------------------------------------------------------------------- int main(int argc, char* argv[]) { int a; cout << "input a: "; cin >> a;
int b; cout << "input b: "; cin >> b;
try { double dd = sqrt(a); Err(); } catch(...) { //здесь a < 0; try { double dd1 = sqrt(b); Err(); } catch(...) { //здесь a < 0 и b < 0 int i = 1;
while (1) { try { double dd2 = a / (a + i); } catch(...) { cout << a << " является максимальным из чисел"; return 1; } try { double dd3 = b / (b + i); } catch(...) { cout << b << " является максимальным из чисел"; return 1; } i++; } } //здесь a < 0 и b >= 0 cout << b << " является максимальным из чисел"; return 1; } //здесь a >= 0 try { double dd4 = sqrt(b); Err(); } catch(...) { // здесь a >= 0 и b < 0 cout << a << " является максимальным из чисел"; return 1; }
// здесь a >= 0 и b >= 0 int j = 0;
while (1) { try { double dd5 = a / (a - j); } catch(...) { cout << b << " является максимальным из чисел"; return 1; }
try { double dd6 = b / (b - j); } catch(...) { cout << a << " является максимальным из чисел"; return 1; } j++; } } Кстати, компилятор MS Visual C++ .NET 2005 генерит код, который корректно ловит все исключения независимо от типа проекта. Вариант для MS Visual C++: private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { int a = 0; int b = -5;
try { while(double::IsNaN(System::Math::Sqrt(a))) throw gcnew Exception(); } catch(...) { //здесь a < 0; try { while(double::IsNaN(System::Math::Sqrt(b))) throw gcnew Exception(); } catch(...) { //здесь a < 0 и b < 0 int i = 1;
while (1) { try { while(double::IsNaN(a / (a + i))) throw gcnew Exception(); } catch(...) { button1->Text = a.ToString()+" является максимальным из чисел"; return; } try { while(double::IsNaN(b / (b + i))) throw gcnew Exception(); } catch(...) { button1->Text = b.ToString()+" является максимальным из чисел"; return; } i++; } } //здесь a < 0 и b >= 0 button1->Text = b.ToString()+" является максимальным из чисел"; return; } //здесь a >= 0 try { while(double::IsNaN(System::Math::Sqrt(b))) throw gcnew Exception(); } catch(...) { // здесь a >= 0 и b < 0 button1->Text = a.ToString()+" является максимальным из чисел"; return; }
// здесь a >= 0 и b >= 0 int j = 0;
while (1) { try { while(double::IsNaN( a / (a - j))) throw gcnew Exception(); } catch(...) { button1->Text = b.ToString()+" является максимальным из чисел"; return; }
try { while(double::IsNaN( b / (b - j) )) throw gcnew Exception(); } catch(...) { button1->Text = a.ToString()+" является максимальным из чисел"; return; } j++; } } Почувствуйте мощь и силу С++ с костылями для новой платформы .. ))) З.Ы. Спасибо товарищу BODROV-у за активную помощь в ловле блох. ))
|
|
|
Записан
|
Говорят, когда компьютер сгорает, перед взором микропроцессора за долю секунды проносятся все операции, которые он когда-либо совершил... 壯鎭
|
|
|
NunTerix
|
|
« Ответ #22 : Июль 24, 2007, 06:58:05 » |
|
Ёпсель как тут много ....
|
|
|
Записан
|
Сердце может прибавить ума, но ум не может прибавить сердца.
|
|
|
LazarusLong
Ирландский доброволец
Проректор
Карма: +181/-7
Offline
Пол: Награды:
Сообщений: 6134
Ukrainian by birth, Irish by the grace of God
|
|
« Ответ #23 : Июль 24, 2007, 08:06:05 » |
|
Кто еще не оптимальнее напишет? Sochin, ладно, идея ясна и имеет право на существование. Никаких требований к оптимальности я не предъявлял, посему +1 . Викторина продолжается. Есть еще один очень простой способ
|
|
|
Записан
|
Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.
"...Он любил говорить факин щит Когда что-то не так ему Принимал он свой самый ирландский вид И кидался трубкой в жену..."
|
|
|
Sochin
Злой модератор
Декан
Карма: +108/-6
Offline
Пол:
Сообщений: 1518
|
|
« Ответ #24 : Июль 24, 2007, 10:16:48 » |
|
Кто еще не оптимальнее напишет? Полагаешь неоптимально использование для организации ветвлений исключений в принципе? Какие другие варианты для ветвлений без использования условных операторов? ))) Самое неоптимально в последнем варианте это сравнение кода ошибки через пересечение множеств, тут уж увы поделать нечего. ))) Викторина продолжается. Есть еще один очень простой способ
Очень интересно глянуть на решение. Надеюсь этот способ относится больше к области программирования, а не математики как первое решение в этом топе. )
|
|
|
Записан
|
Говорят, когда компьютер сгорает, перед взором микропроцессора за долю секунды проносятся все операции, которые он когда-либо совершил... 壯鎭
|
|
|
tendervampire
Бакалавр
Карма: +12/-0
Offline
Пол:
Сообщений: 112
П.Б.Н.
|
|
« Ответ #25 : Июль 24, 2007, 10:31:28 » |
|
Касательно сомнений в возможности прикрутить циклы. Как вариант: void main() { int a,b,r; printf ("Введите первое целочисленное число "); scanf ("%d", &a); printf ("Введите первое целочисленное число "); scanf ("%d", &b); r = abs(a-b); while(r+a-b) { printf("%3d",a); break; }
while(r+b-a) { printf("%3d",b); break; } scanf; }
Надеюсь, обвинений в плагиате не последует
|
|
|
Записан
|
- Our arrows will blind out the sun - Then we will fight in the shade!
|
|
|
LazarusLong
Ирландский доброволец
Проректор
Карма: +181/-7
Offline
Пол: Награды:
Сообщений: 6134
Ukrainian by birth, Irish by the grace of God
|
|
« Ответ #26 : Июль 24, 2007, 11:49:43 » |
|
tendervampireДа, насчет циклов я погорячился. Хотя это просто по сути замена для if - цикл выполняющийся один раз. Да и этот код не будет работать если a и b равны - оба условия циклов равны 0. Sochin, первое решение, приведенное NunTerix'ом - по видимому самое оптимальное. По крайней мере оно оптимальнее моего. Что же твоего решения - то оно является не оптимальным для решения данной конкретной задачи. Для других случаев подобный подход может быть оптимальным, не спорю. Все зависит от задачи. Если хочешь, кстати, могу в ЛС тебе написать свой вариант. Здесь открывать пока не хочется .
|
|
|
Записан
|
Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.
"...Он любил говорить факин щит Когда что-то не так ему Принимал он свой самый ирландский вид И кидался трубкой в жену..."
|
|
|
tendervampire
Бакалавр
Карма: +12/-0
Offline
Пол:
Сообщений: 112
П.Б.Н.
|
|
« Ответ #27 : Июль 25, 2007, 02:04:22 » |
|
Уважаемый LazarusLong! При условии равенства А и Б действительно не происходит никаких действий, но в условии задачи ничего не сказано о равенстве. Прикрутить проверку равенста - сложности не представляет. То, что в данном случае while работает как if не является нарушением условий задачи. Как говорится, в умелых руках... P.S. Сколько раз зарекался не работать без подписанного тех.задания .
|
|
|
Записан
|
- Our arrows will blind out the sun - Then we will fight in the shade!
|
|
|
LazarusLong
Ирландский доброволец
Проректор
Карма: +181/-7
Offline
Пол: Награды:
Сообщений: 6134
Ukrainian by birth, Irish by the grace of God
|
|
« Ответ #28 : Июль 25, 2007, 06:04:23 » |
|
Да ничего против я не имею. Просто считаю, что если, к примеру, в последовательности все элементы равны, это на значит, что в ней нет максимального значения. Просто оно(значение) в таком случае совпадает с минимальным;). А насчет циклов - мне сложно было представить как их использовать в этой задаче в своей первоначальной цели - организации повторяющихся вычислений в программе. Хотя подумав немного придумал . int a=10, b=5; int a1, a2; a1 = a; a2 = a; while((b-a1--)&&(b-a2++)); while(!(b-a1-1)) { cout<<a; exit(0); } cout<<b;
Не пробовал это запускать, но по идее должно работать . Зато здесь цикл как цикл - выполняет повторяющиеся действия . Вот в каком смысле я не представлял использование циклов . Но, как известно, было бы желание, можно и гвозди микроскопом забивать .
|
|
|
Записан
|
Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.
"...Он любил говорить факин щит Когда что-то не так ему Принимал он свой самый ирландский вид И кидался трубкой в жену..."
|
|
|
tendervampire
Бакалавр
Карма: +12/-0
Offline
Пол:
Сообщений: 112
П.Б.Н.
|
|
« Ответ #29 : Июль 25, 2007, 12:09:06 » |
|
Начинает происходит типичное для невербального общения непонимание Это, конечно, похоже на флуд, но вот варинт с проверкой равенства: void main() { int a,b,r; printf ("Введите первое целочисленное число "); scanf ("%d", &a); printf ("Введите первое целочисленное число "); scanf ("%d", &b); r = abs(a-b); while(r+a-b) { printf("%3d",a); getch(); return a; }
while(r+b-a) { printf("%3d",b); getch(); return b; } printf("Значения одинаковы a и b: %3d",a); getch(); return a; }
Принцип вычисления для последовательностей с l>2 - как для вычисления НОК. Схематично: int Max(int a,int b) { // сюда пишем то, что выше } int mas[10]; a = mas[0]; for(int i=1;i<10;i++) a = Max(a,mas[i]) return a;
Безусловно, вариант не оптимальный. Вариант NunTerix'a куда лучше. Но с if не сравнить Насчет применения в реальной жизни - если мне придется писать на языке, который будет похож на указанный в задании, я с создателем языка сделаю что-нибудь плохое томиком Стауструпа А насчет гвоздей и микроскопа - всякое в жизни бывает, вдруг, забивание гвоздя - дело жизни и смерти
|
|
|
Записан
|
- Our arrows will blind out the sun - Then we will fight in the shade!
|
|
|
LazarusLong
Ирландский доброволец
Проректор
Карма: +181/-7
Offline
Пол: Награды:
Сообщений: 6134
Ukrainian by birth, Irish by the grace of God
|
|
« Ответ #30 : Июль 25, 2007, 05:43:30 » |
|
Ладно. Замнем для ясности. +1. Насчет языка. Дык без ограничений сильно просто было бы и не интересно . Ясное дело, что на таком языке без условных операторов и всего прочего вряд ли придется писать Кстати мне сегодня пришла в голову еще одна идея как можно решить данную задачу. Как то обыграть ситуацию, что а/b = 0 если а меньше b и не 0 в противном случае. Правда, будет работать только для а>=0, b>0.
|
|
|
Записан
|
Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.
"...Он любил говорить факин щит Когда что-то не так ему Принимал он свой самый ирландский вид И кидался трубкой в жену..."
|
|
|
tendervampire
Бакалавр
Карма: +12/-0
Offline
Пол:
Сообщений: 112
П.Б.Н.
|
|
« Ответ #31 : Июль 25, 2007, 06:59:10 » |
|
Интересно, можно подумать. b==0 можно отловить exception'ом. А +/- можно отловить опять же while( znach+abs(znach)) . Но в итоге получается самый неоптимальный вариант из всех представленных )) А для неотрицательных - очень даже симатично.
|
|
|
Записан
|
- Our arrows will blind out the sun - Then we will fight in the shade!
|
|
|
naxellar
Главный флудер
Проректор
Карма: +101/-52
Offline
Пол:
Сообщений: 5015
Главный флудер
|
|
« Ответ #32 : Июль 26, 2007, 01:32:37 » |
|
Загляни в какой нибудь справочник по С и скажи мне какая функция абсолютного значения?
abs, fabs, etc. Причем fabs для вещественных чисел, которыми тут и не пахнет
|
|
|
Записан
|
|
|
|
NunTerix
|
|
« Ответ #33 : Июль 26, 2007, 09:15:40 » |
|
fabs - только для вещественных чисел?
|
|
|
Записан
|
Сердце может прибавить ума, но ум не может прибавить сердца.
|
|
|
naxellar
Главный флудер
Проректор
Карма: +101/-52
Offline
Пол:
Сообщений: 5015
Главный флудер
|
|
« Ответ #34 : Июль 26, 2007, 09:19:33 » |
|
fabs - только для вещественных чисел? Не думаю, что только, но она не нужна так как есть обычная abs (Я так понял)
|
|
|
Записан
|
|
|
|
tendervampire
Бакалавр
Карма: +12/-0
Offline
Пол:
Сообщений: 112
П.Б.Н.
|
|
« Ответ #35 : Июль 26, 2007, 12:06:55 » |
|
По результату, abs и fabs идентичны. Просто abs в чистом с отсутствует. А с++ без разницы, что использовать.
|
|
|
Записан
|
- Our arrows will blind out the sun - Then we will fight in the shade!
|
|
|
NunTerix
|
|
« Ответ #36 : Июль 26, 2007, 05:18:20 » |
|
По результату, abs и fabs идентичны. Просто abs в чистом с отсутствует.
Ну вот .... а писалось, предполагая, что только на С ... так что naxellar нужна ....
|
|
|
Записан
|
Сердце может прибавить ума, но ум не может прибавить сердца.
|
|
|
LazarusLong
Ирландский доброволец
Проректор
Карма: +181/-7
Offline
Пол: Награды:
Сообщений: 6134
Ukrainian by birth, Irish by the grace of God
|
|
« Ответ #37 : Июль 26, 2007, 07:12:38 » |
|
abs есь и в С. Вернее в Сишном math.h - есть функция abs со следующим прототипом: int abs(int). Кроме того: double fabs(double) long labs(long) и еще для комплексных чисел
|
|
|
Записан
|
Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.
"...Он любил говорить факин щит Когда что-то не так ему Принимал он свой самый ирландский вид И кидался трубкой в жену..."
|
|
|
Sochin
Злой модератор
Декан
Карма: +108/-6
Offline
Пол:
Сообщений: 1518
|
|
« Ответ #38 : Июль 26, 2007, 07:19:57 » |
|
Я не пойму из-за чего весь спор? Тип int приводится к типу double, так что вариант fabs годится. )
|
|
|
Записан
|
Говорят, когда компьютер сгорает, перед взором микропроцессора за долю секунды проносятся все операции, которые он когда-либо совершил... 壯鎭
|
|
|
LazarusLong
Ирландский доброволец
Проректор
Карма: +181/-7
Offline
Пол: Награды:
Сообщений: 6134
Ukrainian by birth, Irish by the grace of God
|
|
« Ответ #39 : Июль 26, 2007, 07:36:37 » |
|
То что int приводится к double это ясно. А double приводится к int? Ведь в варианте NunTerix'a нужно как раз именно такое приведение.
|
|
|
Записан
|
Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.
"...Он любил говорить факин щит Когда что-то не так ему Принимал он свой самый ирландский вид И кидался трубкой в жену..."
|
|
|
|