Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Ошибка вычисления деления калькулятора на С# (http://forum.oszone.net/showthread.php?t=218890)

Ksenya 25-10-2011 20:18 1781577

Ошибка вычисления деления калькулятора на С#
 
Вложений: 1
Здрасьте. мною написан, уже в полузавершенном варианте инженерный калькулятор..В момент написания кода к действию "деления" само действие работало прекрасно, но после добавления след строк по действиям до существующего конца программы..возникает непонятная ошибка) (причем ничего изменено не было). Подскажите в чем дело..почти дописан(

Папочку с кодом предлагаю для рассмотрения.

LilLoco 25-10-2011 22:02 1781663

Цитата:

Цитата Ksenya
возникает непонятная ошибка »

Опять тот же вопрос :) Что за ошибка?

Цитата:

Цитата Ksenya
Подскажите в чем дело »

Где именно смотреть? Скачал проект, но что - то в нем не так, не хватает Form1.Designer.cs, скорее всего :)

Ksenya 25-10-2011 23:31 1781745

:) перезалила

LilLoco 26-10-2011 07:47 1781867

Ksenya, Так как вы снова не указали ошибку и место где она возникает, буду угадывать...

При делении у вас всегда выводится "Деление на ноль невозможно" .
Это из - за того, что вы обнуляете переменную, заносите ее в поле и потом его парсите:
Код:

            double answer = 0; // вот тут обнуление у вас
            if (ch == '+')
            { answer = Temp + double.Parse(textBox1.Text); }
            if (ch == '-')
            { answer = Temp - double.Parse(textBox1.Text); }
            if (ch == '*')
            { answer = Temp * double.Parse(textBox1.Text); }
            if (ch == '^')
            { answer = Math.Pow(Temp, double.Parse(textBox1.Text)); }
            if (ch == 'k')
            { answer = SqrtY(Temp); }
            if (ch == 'm')
            { answer = Temp % double.Parse(textBox1.Text); }


            textBox1.Text = answer.ToString();  // здесь вы в поле текстбокс1 вносите "0"
            textBox2.Text = textBox1.Text;

            if (ch == '/')
            {
// а тут начинаете парсить, в итоге первое условие никогда не выполнится, только если равно нулю.
                if (double.Parse(textBox1.Text) != 0) { answer = Temp / double.Parse(textBox1.Text); }
                else if (double.Parse(textBox1.Text) == 0)
                {
                    textBox1.Text = "Деление на ноль невозможно";
                    textBox2.Text = textBox1.Text; System.Media.SystemSounds.Asterisk.Play();
                }
            }

И еще, просто совет, на примере этого же куска кода. Не делайте просто через if, лучше использовать else if. Будет выполняться меньше проверок, тем самым оптимизируете работу.

Код:

            if (ch == '+')
            { answer = Temp + double.Parse(textBox1.Text); }
            else if (ch == '-')
            { answer = Temp - double.Parse(textBox1.Text); }
            else if (ch == '*')
            { answer = Temp * double.Parse(textBox1.Text); }
            esle if (ch == '^')
            { answer = Math.Pow(Temp, double.Parse(textBox1.Text)); }
....


ferget 26-10-2011 08:20 1781882

и еще с блоком проверки деления на ноль проблема

Код:

            if (ch == '/')
            {
                if (double.Parse(textBox1.Text) != 0) { answer = Temp / double.Parse(textBox1.Text); }
                else if (double.Parse(textBox1.Text) == 0)
                {
                    textBox1.Text = "Деление на ноль невозможно";
                    textBox2.Text = textBox1.Text; System.Media.SystemSounds.Asterisk.Play();
                    return;
                }
            }
            textBox1.Text = answer.ToString();
            textBox2.Text = textBox1.Text;


Ksenya 26-10-2011 19:21 1782353

Да, но тогда возникает ошибка, я писала о ней в пред теме..(использование переменной, которой не присвоено значение(скриншот в дополнение)
и тогда напрашивается другой вопрос: почему другие действия не становятся равными нулю? магия, как вы думаете? :)

ferget 26-10-2011 19:29 1782358

Цитата:

Цитата Ksenya
но тогда возникает ошибка »

тогда это когда?

и где скриншот?

Ksenya 26-10-2011 19:32 1782366

извините, "Общая квота форума превышена на 117.6 Kb. " , не получилось. (Когда оставляю просто:
Код:

private void button_answ_Click(object sender, EventArgs e)
        {  double answer; // без "=0"
            if (ch == '+')
            { answer = Temp + double.Parse(textBox1.Text); }

догадалась, надо просто этот этап выполнить последним;)
Код:

private void button_answ_Click(object sender, EventArgs e)
        {
          double answer=0;
            if (ch == '+')
            { answer = Temp + double.Parse(textBox1.Text); }
            if (ch == '-')
            { answer = Temp - double.Parse(textBox1.Text); }
            if (ch == '*')
            { answer = Temp * double.Parse(textBox1.Text); }
            if (ch == '^')
            { answer = Math.Pow(Temp, double.Parse(textBox1.Text)); }
            if (ch == 'k')
            { answer = SqrtY(Temp); }
           

         

            if (ch == '/')
            {
                if (double.Parse(textBox1.Text) != 0)  answer = Temp / double.Parse(textBox1.Text);
                else if (double.Parse(textBox1.Text) == 0)
                {
                    textBox1.Text = "Деление на ноль невозможно";
                    textBox2.Text = textBox1.Text; System.Media.SystemSounds.Asterisk.Play();
                }
            }
            if (ch == 'm')
            { answer = Temp % double.Parse(textBox1.Text); }
           
            textBox1.Text = answer.ToString();
            textBox2.Text = textBox1.Text;
        }

вот я чучело-мяучело=*
спасибо ребят..;)

эх и намучилась я с ним, с этим калькулятором, есть кстати полу-почти-инженерный исходник, но он мудреный слишком и с ошибками, тоже с делением..препод завалит.(

а вот такой вопрос..перерыла кучу литературы, но так и не смогла найти инф-ию по нахождению факториала от отрицательного дробного числа в с# .. это что в природе не возможно на данном языке? (потому как нашла только дэлфийский)

Ksenya 26-10-2011 20:03 1782383

нет, работает не так..потому что после нахождения деления, к примеру деления на ноль, не выводит сообщение в textbox пользователю, о том что он ошибся. а как избавится от записи double answer=0; или что-то в этом роде?

LilLoco 26-10-2011 21:43 1782459

Цитата:

Цитата Ksenya
потому как нашла только дэлфийский »

Ну алгоритм значит есть, остается только перевести на другой язык...
Цитата:

Цитата Ksenya
нет, работает не так..потому что после нахождения деления, к примеру деления на ноль, не выводит сообщение в textbox пользователю, о том что он ошибся »

воообще не понятно, что не так

Цитата:

Цитата Ksenya
а как избавится от записи double answer=0 »

Зачем от нее избавляться?

ferget 26-10-2011 21:56 1782474

Цитата:

Цитата Ksenya
потому что после нахождения деления, к примеру деления на ноль, не выводит сообщение в textbox пользователю, о том что он ошибся »

на самом деле выводит, но функция продолжает выполнятся и значение меняется на 0
из функции надо выйти

Код:

                    textBox1.Text = "Деление на ноль невозможно";
                    textBox2.Text = textBox1.Text; System.Media.SystemSounds.Asterisk.Play();
                    return;


Ksenya 26-10-2011 23:11 1782523

Вложений: 1
видели б вы какой он страшный..могу привести..не разобрать просто)) (код дэлфийский)

Ksenya 26-10-2011 23:18 1782528

Цитата:

на самом деле выводит, но функция продолжает выполнятся и значение меняется на 0
из функции надо выйти
точно)) спасибо..

LilLoco 27-10-2011 07:38 1782659

Вот тут можно посмотреть про факториал дробного числа. А так, в принципе, ищите гамма - функции.

Ksenya 27-10-2011 18:45 1783127

Вложений: 1
Нет, я окончательно решила отказаться от такого каркаса, так как возникла идея создать все намного грамотнее и красивее..код, требующий доработки до полного инженерного, также отказывается выполнять деление( в частности на ноль, как странно бы не звучало)..

Ни ошибки исключений, ни какие-либо другие записи в поле "ответа" не выводятся ..я извиняюсь, но если есть возможность посмотреть, оцените пожалуйста насколько мои шансы доделать это действие делимы на ноль. :) :dont-know
Файл содержит пояснения, то насколько мне удалось разобраться..(наверно будет слегка не литературно)

В частности в месте:
Код:

//блок выполнения операций
        private double ExecuteOperation(double DoubResul, double num, Operation op)
        {
                switch (op)//в зависимости от переменной для операций
                {
                    case Operation.Add:
                        {
                            DoubResul = DoubResul + num;
                            return DoubResul;
                        }
                    case Operation.Div:
                        {    if (num == 0) { DoubResulLast=DoubResul; label_number.Text= "Деление на ноль невозможно!: " ;
                return 0; }
            else
                            DoubResul = DoubResul / num;
                            return DoubResul;
                        }
                    case Operation.Mult:
                        {
                            DoubResul = DoubResul * num;
                            return DoubResul;
                        }
                    case Operation.Sub:
                        {
                            DoubResul = DoubResul - num;
                            return DoubResul;
                        }
                    case Operation.Per:
                        {
                            DoubResul = (DoubResul * num) / 100;
                            return DoubResul;
                        }
                    case Operation.Sqrt:
                        {
                            DoubResul = Math.Sqrt(num);
                            return DoubResul;
                        }
                    case Operation.DivX:
                        {
                            DoubResul = 1 / num;
                            return DoubResul;
                        }
                    case Operation.Mod:
                        {
                            DoubResul = DoubResul % num;
                            return DoubResul;
                        }
                    default: return DoubResul;
              //}
            }
            /*catch (DivideByZeroException ex) ---> тоже не срабатывает
            {
                label_number.Text = "Деление на ноль невозможно!: " + ex.Message;
                return 0;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка!: " + ex.Message);
                return 0;
            }*/
        }

ошибка именно в выполнении действия в процессе отладки
__
как разрешить такое:Общая квота форума превышена на 105.6 Kb. Пожалуйста, сообщите об этом администрации..

ferget 27-10-2011 19:01 1783137

Вложений: 1
выложите весь проект



вот вроде работает

Delirium 28-10-2011 01:06 1783371

Цитата:

Цитата Ksenya
как разрешить такое:Общая квота форума превышена на 105.6 Kb. Пожалуйста, сообщите об этом администрации.. »

Общий объем доступного места на форуме для вложений зависит от количества сообщений пользователя. Т.к. вы новичок => и объем маленький.

Ksenya 28-10-2011 01:59 1783384

Цитата:

ferget:вот вроде работает
да, все как надо) спасибо
...
еще возник такой момент,: если в Дэлфи функция: delete(st,length(st),1); смогла бы удалить нам последний символ в строке..то вроде как в С# аналогов этому не существует. И если пойти через свойство длины строки:
Код:

Convert.ToString(DoubResul).Lenght = Convert.ToString(ExecuteOperation(DoubResul, Num, CurrOper)).Lenght - 1;
светлого решения проблемы точно не увидишь, похоже что в доступных функциях, как в немногих других языках, # каким-то образом обделен..

Delirium 28-10-2011 02:37 1783393

Цитата:

Цитата Ksenya
.то вроде как в С# аналогов этому не существует »

Вовсе нет. делается так:

Код:

string str = "some text";
str = str.Substring(0, str.Length-1);


Цитата:

Цитата Ksenya
Convert.ToString(DoubResul).Lenght »

Гораздо проще написать DoubResul.ToString().Length

LilLoco 28-10-2011 17:57 1783786

Цитата:

Цитата Delirium
Цитата Ksenya:
.то вроде как в С# аналогов этому не существует »
Вовсе нет. делается так: »

Ну или так :
Код:

string str = "OsZone!";
str = str.Remove(str.Length-1);
// в str будет "OsZone"

Удаляет последний символ...

Ksenya 29-10-2011 15:21 1784330

Вложений: 1
Наверно, все это прекрасно работает, только не в моем коде..калькулятор отказывается выполнять мои требования. :(

ferget 29-10-2011 16:25 1784366

Код:

private void button_del_Click(object sender, EventArgs e)
        {
            label_number.Text = label_number.Text.Remove(label_number.Text.Length - 1);
            if (label_number.Text == "")
                label_number.Text = "0";
        }


Ksenya 29-10-2011 17:32 1784412

Вложений: 1
ferget, да, такой вариант сработает, просто в коде отсутствуют операции Click-ов, действия всех кнопок распознает метод - Operation ReturnOperation(((Button)sender).Text); действия для отобранной операции: либо - double ExecuteOperation(double DoubResul, double num, Operation op), либо - как например, для обнуления экрана(Clr) - void UnarOperationEvent(object sender, EventArgs e).. просто потом, подумав и переделываю чисто под стереотип, (не забывая про void и double).. получаю тот же самый игнор. Т.е глубже копая, по нажатию на кнопку в конструкторе он ссылается на ButtonClick, вместо UnarOperation, как другие(например, √ ) и другие..

ferget 29-10-2011 21:05 1784542

btn_clr_num работает неправильно, только с унарными операциями работает, а с обычными нет

Цитата:

Цитата Ksenya
просто в коде отсутствуют операции Click-ов »

они есть у button_dot, button_clear и button_chs которые работают правильно

Ksenya 29-10-2011 21:37 1784576

Да, причем попробуйте сделать следующее: поменяйте код действий( например у √ и нашей стрелки, увидите, что стрелка вычисляет, а корень наоборот нет) . в чем-то подвох, исходник не мой, ноя в нем почти разобралась, вероятно закрыт доступ не родным визуальным объектам на форме? мистика

ferget 29-10-2011 22:17 1784599

Цитата:

Цитата Ksenya
мистика »

не мистика

просто кнопки изначально были разбиты на группы по действиям:

унарные

бинарные

ввод числа

память

и по одной, кнопки не связанные с вычислениями

button_dot, button_clear, button_chs

вы добавляете кнопки не связанные с вычислениями и привязываете их к группам по действиям, что неправильно

нужно или сделать их отдельными или выделить в особую группу

Ksenya 29-10-2011 22:35 1784607

просто я пробовала добавить новые кнопки с действием, к примеру корня, в итоге поняла, что они мои кнопочки обделены) (привязывала к унарным)

ferget 29-10-2011 22:59 1784621

Вложений: 1
Вот вариант, вроде все кнопки работают

Ksenya 29-10-2011 23:36 1784640

точно! вы правы, спасибо :yes: а если я добавлю другие операции, унарные/бинарные на новых кнопках, они сработают, если прописать их в группах? пробую, пока не получается(

Ksenya 30-10-2011 02:32 1784734

Вложений: 1
и еще такой вопрос, про использование скобок. Нужен новый класс, я полагаю..вот как в примере..только как его связать со скобками и вычислениями..
нет уже сил с этим калькулятором :o

lxa85 30-10-2011 08:05 1784752

Ksenya, отслеживаю тему, все никак руки не дойдут до трассировки.
Опиши пожалуйста на словах принцип разбора выражения и его расчета.
Т.е. при введении скобок и сложных выражений, с разделением приоритетов выполнения операций, могут применяться различные типы разбора строки.
Как пример - Польская обратная запись. Она может строиться с помощью стека, может строиться с помощью дерева. Я в свое время писал на Delphi не слишком быстрый, многопроходный разбор выражения в дерево.

OPZ - как я понимаю и есть Польская обратная запись. С принципом ее работы разобрались?
К ночи постараюсь взглянуть на код.
----
ferget, LilLoco, :up

Ksenya 30-10-2011 19:13 1785178

Здрасьте, lxa85.) честно говоря не совсем) да, на 2 курсе опз рассматривали, и для моего калькутера я выбрала наиболее подходящий вариант опз. исходник. но он применим для консольного калькулятора, это во-первых, а во-вторых, там совершенно другие входные данные, которые меня и смущают, пусть я переименую их, когда распознаю, к примеру как сейчас - числовые данные, которые я ввожу в поле - label_number.Text =(с обработкой операции и получением резалта)= Convert.ToString(ExecuteOperation(DoubResul, Num, CurrOper));.

Но как использовать определяемые, с помощью ОПЗ, данные для наших операций..просто мозги набекрень, это что мне теперь под один этот класс придется переделывать всю главную программу? потому как:
//заменить умножение или деление в строке InBrackets на посчитанное значение
Код:

  public void repMD(int i) {
      double MD;
        if (InBrackets[i] == '*')
            MD = GetLeftOperand(i) * GetRightOperand(i);// ладно, пускай в нашем случае-вместо MD-результат прописывался как-DoubResul
        else
            MD = GetLeftOperand(i) / GetRightOperand(i);
        ReplaceExp(i, MD);
        Calc(); //вернуться в метод Calc - получается, что-то вроде взаимной рекурсии
    }

или как-то совместить: метод определения опреации по тексту нажатой Button - private Operation ReturnOperation(string str_op)
и систему ОПЗ для выражений со скобками?

lxa85 30-10-2011 21:15 1785247

я трассировку то конечно выполню, но я ничего не понял, из того, что ты сказала :(
Напиши словами.
Цитата:

Цитата Ksenya
Convert.ToString(ExecuteOperation(DoubResul, Num, CurrOper));. »

Вот это выражение нам что возвращает?
repMD - что за зверь? Как звучит полностью?
Система ОПЗ со скобками вообще не работает. Как сказать то...
Первая задача - перевести выражение в ОПЗ.
Вторая задача - по полученной ОПЗ посчитать выражение.
Блок схемку приведи, иль еще чего. Т.е. нужны смысловые блоки (ищем операцию, инициализируем переменные и т.п.) и тогда можно будет программу структурировать и понимать, за что отвечает тот или иной блок операторов.
----
Программы скачал, сейчас буду разбираться.

Ksenya 30-10-2011 22:33 1785298

ага, значит, это выражение выдает нам ответ, вычисленный по методу расчета операций( "+","-","*","/" и других) и переведенный в окошко label_number.Text в строковом формате. т.е сначала после нажатия кнопок с текстами: цифра - знак операции-цифра ..срабатывает метод ReturnOperation(он выдает то или иное название операции), ..затем..после нажатия кнопки "="..срабатывает вложенный цикл методов: ExecuteOperation(DoubResul, Num, CurrOper)) - get_answer();- OperationEvent(object sender, EventArgs e). Как теперь включать опз, не меняя координально структуру, причем ведь еще есть операции: "√", возведения в степень(включу потом со старой версии калькулятора) ..
ума не приложу.


Время: 21:03.

Время: 21:03.
© OSzone.net 2001-