Ошибка деление на ноль делфи

PharatriX

0 / 0 / 0

Регистрация: 04.11.2015

Сообщений: 13

1

Добавить ошибку «на ноль делить» нельзя

12.11.2015, 01:06. Показов 5761. Ответов 7

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

В код калькулятора при делении на ноль нужно добавить ошибку «на ноль делить нельзя»

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
var
  Form1: TForm1;
  num1,num2:real;
  doit:string;
 
implementation
 
uses Unit2;
 
{$R *.dfm}
 
procedure TForm1.Button23Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+'7';
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+'8';
end;
 
procedure TForm1.Button3Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+'9';
end;
 
procedure TForm1.Button4Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+'4';
end;
 
procedure TForm1.Button5Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+'5';
end;
 
procedure TForm1.Button6Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+'6';
end;
 
procedure TForm1.Button7Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+'1';
end;
 
procedure TForm1.Button8Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+ '2';
end;
 
procedure TForm1.Button9Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+'3';
end;
 
procedure TForm1.Button27Click(Sender: TObject);
begin
Edit1.Text:=Edit1.Text+'0';
end;
 
procedure TForm1.Button10Click(Sender: TObject);
begin TRY
num1:=StrToFloat(Edit1.Text);
doit:='плюс';
Edit1.Clear;
Edit1.SetFocus;
EXCEPT
on EConvertError do
begin
showmessage('Error');
end;
end;
end;
 
procedure TForm1.Button11Click(Sender: TObject);
begin try
num1:=StrToFloat(Edit1.Text);
doit:='минус';
Edit1.Clear;
Edit1.SetFocus;
EXCEPT
on EConvertError do
begin
showmessage('Error');
end;
end;
 
 
end;
 
procedure TForm1.Button12Click(Sender: TObject);
begin try
num1:=StrToFloat(Edit1.Text);
doit:='разделить';
Edit1.Clear;
Edit1.SetFocus;
EXCEPT
on EConvertError do
begin
showmessage('Error');
end;
end;
end;
 
procedure TForm1.Button13Click(Sender: TObject);
begin try
num1:=StrToFloat(Edit1.Text);
doit:='умножить';
Edit1.Clear;
Edit1.SetFocus;
EXCEPT
on EConvertError do
begin
showmessage('Error');
end;
end;
end;
 
procedure TForm1.Button28Click(Sender: TObject);
begin
if Pos(',',Edit1.Text)<>0 then Exit
else
Edit1.Text:=Edit1.Text+',';
end;
 
procedure TForm1.Button16Click(Sender: TObject);
begin
Edit1.Clear;
num1:=0;
num2:=0;
doit:=' ';
Edit1.SetFocus;
end;
 
procedure TForm1.Button15Click(Sender: TObject);
var s:string;
begin try 
edit1.Text:=floattostr(-(strtofloat(Edit1.Text))); 
except 
on EConvertError do begin 
showmessage('Error');
end;
end; 
end;
 
 
procedure TForm1.Button14Click(Sender: TObject);
begin  try
num2:=StrToFloat(Edit1.Text);
if doit='плюс'
then Edit1.Text:=FloatToStr(num1+num2);
if doit='минус'
then Edit1.Text:=FloatToStr(num1-num2);
if doit='умножить'
then Edit1.Text:=FloatToStr(num1*num2);
if doit='разделить' then
Edit1.Text:=FloatToStr(num1/num2);
if doit='степень'
then Edit1.Text:=FloatToStr(exp(num2*ln(num1)));
num1:=0;
num2:=0;
doit:=' ';
Edit1.SetFocus;
EXCEPT
on EConvertError do
begin
showmessage('Error');
end;
end;
 
end;



0



3035 / 2217 / 511

Регистрация: 11.09.2009

Сообщений: 8,197

12.11.2015, 01:46

2

Перед делением проверяйте значение делителя. Если ноль — выводите «на ноль делить нельзя» и отменяете операцию.



0



0 / 0 / 0

Регистрация: 04.11.2015

Сообщений: 13

12.11.2015, 02:39

 [ТС]

3

Когда я проверяю , то и при умножении на 0 выводит ошибку, что на ноль делить нельзя , не знаю ,как это исправить



0



3035 / 2217 / 511

Регистрация: 11.09.2009

Сообщений: 8,197

12.11.2015, 02:51

4

Цитата
Сообщение от PharatriX
Посмотреть сообщение

Когда я проверяю , то и при умножении на 0 выводит ошибку, что на ноль делить нельзя , не знаю ,как это исправить

Значит проверку вставили не в то место.

Цитата
Сообщение от i8085
Посмотреть сообщение

Перед делением проверяйте значение делителя.



0



algol

1 / 1 / 1

Регистрация: 25.03.2014

Сообщений: 19

12.11.2015, 07:21

5

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
procedure TForm1.Button14Click(Sender: TObject);
begin  
  try
    num2 := StrToFloat(Edit1.Text);
  except
    on Exception : EConvertError do
       ShowMessage(Exception.Message);
  end;
 
  if doit='плюс'      then Edit1.Text := FloatToStr(num1+num2) else
  if doit='минус'     then Edit1.Text := FloatToStr(num1-num2) else
  if doit='умножить'  then Edit1.Text := FloatToStr(num1*num2) else
  if doit='степень'   then Edit1.Text := FloatToStr(exp(num2*ln(num1))) else
  if doit='разделить' then 
    if num2 <> 0 then Edit1.Text := FloatToStr(num1/num2)
    else begin
      ShowMessage('Деление на ноль');
      Edit1.text := Format('%d/%d', [num1, num2]);
    end;
 
  num1 := 0;
  num2 := 0;
  doit := '';
  Edit1.SetFocus;
end;



0



841 / 736 / 342

Регистрация: 22.09.2012

Сообщений: 5,034

12.11.2015, 12:00

6

PharatriX, Добавить ошибку «на ноль делить» нельзя

В программу ошибки лучше недобавлять.
Лучше добавлять сообщения об ошибках — если они происходят в программе.



0



W

115 / 115 / 33

Регистрация: 16.04.2013

Сообщений: 748

13.11.2015, 08:31

7

Цитата
Сообщение от PharatriX
Посмотреть сообщение

«на ноль делить нельзя»

Та можно — бесконечность будет в результате. Вот ее значек и выводи в ответ.



0



1 / 1 / 1

Регистрация: 25.03.2014

Сообщений: 19

13.11.2015, 08:43

8

Вы не правы.
В обычной арифметике деление на ноль не имеет смысла, так как:

1). При а ≠ 0 не существует числа, которое при умножении на 0 даёт а, поэтому ни одно число не может быть принято за частное а⁄0;
2). При а = 0 деление на ноль также не определено, поскольку любое число при умножении на 0 даёт 0 и может быть принято за частное 0⁄0.



0



Это очень полезный инструмент ,и, кроме того, очень распространенный. Не знаю, как вы искали в гугле, если ничего не нашли на эту тему…

Конструкция

Try -> EXCEPT -> END

управляет поведением возможной исключительной ситуацией, которая может возникнуть в секции «TRY». Если такая возникает, то выполнение кода в секции «TRY» прекращается и моментально перепрыгивает в начало секции «EXCEPT» и код, находящийся там, выполняется до конца, т.е до «END». Рассмотрим пример обработки исключительной ситуацией «EZeroDevide»(деление на ноль) :

...
var
  a: integer;
  ...
begin
  try
    a := 1/0; 
  except
    on EZeroDivide do showmessage('Divide by zero not allowed!'); // обработка КОНКРЕТНОЙ исключителной ситуации
  end;
end;

Также существует еще одна конструкция обработки исключительных ситуаций:

TRY -> FINALLY -> END

Данный блок функционирует немного иначе: если в секции «TRY» возникнет исключительная ситуация, то выполнение кода оставновится в этой секции и перепрыгнет в секцию «FINALLY».
Но даже если никакой исключительной ситуации не возникнет, то в конце выполнения кода в «TRY», секция «FINALLY» все равно будет выполнена. Эту конструкцию уместно применять, если в конце работы надо произвести операции по, например, освобождению памяти. Пример:

1 случай:

...
try
  a := 1/0; 
finally
  showmessage('Divide by zero not allowed!');
end;
...

2 случай:

...
try
  a := 1/1; 
finally
  showmessage('Divide by zero not allowed!');
end;
...

В обоих случаях будет выведено сообщение.

I know how to do basic exception handling. So i can raise a message on divide by zero using the ‘try except’ method.

What i would like to do is, find the variable that causes this error and then change its value on run time.

For Ex:

procedure Calculate();
var
  a, b, c : Double;
begin
  try
    a := 4; //suppose i take this value from user and he enters 4
    b := 0; //suppose i take this value from user and he enters 0
    c := a/b;
    ShowMessage(FloatToStr(c));
  except
    on E : EZeroDivide do
    begin
      ShowMessage('Exception message = '+E.Message);

//i am not sure how to identify that its variable 'b' that is causing the error and has to be changed by a default value

      get(E....errorVaraiable);
      E....errorVaraiable := 0.00001;
      c := a/E....errorVariable;

      ShowMessage(FloatToStr(c));
    end;
  end;

Please, can anyone help me with this?

asked May 24, 2013 at 12:45

Arjun's user avatar

8

Here’s a modified version of your example that does what you want.

procedure Calculate();
var
  a, b, c : Double;
begin
  a := 4; //suppose i take this value from user and he enters 4
  b := 0; //suppose i take this value from user and he enters 0
  if IsZero(b) then
  begin
    ShowMessage('b cannot be 0')
  end
  else 
  begin
    c := a/b;
    ShowMessage(FloatToStr(c));
  end; 
end;

answered May 24, 2013 at 13:09

Wouter van Nifterick's user avatar

6

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.


    Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
    1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
    2. Как «свернуть» программу в трей.
    3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
    4. Как прочитать список файлов, поддиректорий в директории?
    5. Как запустить программу/файл?
    … (продолжение следует) …


    Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
    Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


    Внимание
    Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
    Повторная попытка — 60 дней. Последующие попытки бан.
    Мат в разделе — бан на три месяца…

    >
    ДЕление на 0 в DELPHI 2007
    , Почему не выскакивает ошибка ?

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему



    Сообщ.
    #1

    ,
    18.06.10, 05:51

      ExpandedWrap disabled

        procedure TForm8.FormCreate(Sender: TObject);

        var

        d:Double;

        begin

         d := 12/0;

         d:=d*2;

         Self.Tag := Trunc(D*2);//Ошибка вылетает только здесь, но по идее должна же вылетать на делении

        end;

      В инете находил инфу только по констатации факта, что для того, чтобы было корректно и вылетала ошибка, шужно делать через переменную.

      ExpandedWrap disabled

        procedure TForm8.FormCreate(Sender: TObject);

        var

        d,с:Double;

        begin

         с := 12;

         d := c/0;

         d:=d*2;

         Self.Tag := Trunc(D*2);//Ошибка вылетает только здесь, но по идее должна же вылетать на делении

        end;

      Вот так ошибка уже не вылетает. ВОпрос. МОжно ли в настройках дельфи сделать так, чтобы ошибку выдавалобез переменной С сразу при делении 12 на 0?

      Сообщение отредактировано: Marriage — 18.06.10, 05:53

      Master

      Chow



      Сообщ.
      #2

      ,
      18.06.10, 07:24

        Гм, может я не прав, но при чем тут Делфи вообще?
        Ошибка деления на 0 возникает только для целых типов.
        У вас же — Double. Там никаких ошибок быть не может т.к. результат деления на 0 — Inf (специальное значение для форматов с плавающей запятой. Еще есть NaN).


        leo



        Сообщ.
        #3

        ,
        18.06.10, 09:12

          Цитата Marriage @ 18.06.10, 05:51

          МОжно ли в настройках дельфи сделать так, чтобы ошибку выдавало без переменной С сразу при делении 12 на 0?

          Видимо нет, т.к. компилятор воспринимает константное выражение d:=12/0 как «осознанное» присвоение переменной d значения Infinity, вполне допустимое для вещественных чисел. Соотв-но встречая 12/0 компилятор ничего не делит, а просто заменяет деление присвоением d:=Infinity

          Цитата Chow @ 18.06.10, 07:24

          Ошибка деления на 0 возникает только для целых типов.
          У вас же — Double. Там никаких ошибок быть не может т.к. результат деления на 0 — Inf

          С поправкой, что это относится только к константам, т.к. при явном делении в рантайме d:=c/0 ошибка EZeroDivide ес-но возникает (если ее специально не маскировать вызовом SetExceptionMask)


          SPrograMMer



          Сообщ.
          #4

          ,
          18.06.10, 13:41

            все гораздо проще… компилятор оптимизирует строчки:

            ExpandedWrap disabled

              d := 12/0;

               d:=d*2;

               Self.Tag := Trunc(D*2);

            в

            ExpandedWrap disabled

              Self.Tag := Trunc((12/0)*2*2);

            может даже быть так, что переменная в опертивной памяти не наблюдается


            leo



            Сообщ.
            #5

            ,
            18.06.10, 14:15

              Цитата SPrograMMer @ 18.06.10, 13:41

              все гораздо проще…

              А что проще то ? По любому при наличии в константном выражении деления на 0 компилятор заменяет все выражение на Infinity, которое для процессора является вполне легальным значением и соотв-но ни его загрузка в FPU, ни умноженияделения и т.п. на конечные значения не вызывают никаких исключений. Поэтому независимо от того соптимизирует компилятор вычисления или нет, ошибка тут будет не EZeroDivide, а EInvalidOp при попытке преобразовать Infinity к целому числу через Trunc

              Сообщение отредактировано: leo — 18.06.10, 14:17

              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

              0 пользователей:

              • Предыдущая тема
              • Delphi: Общие вопросы
              • Следующая тема

              Рейтинг@Mail.ru

              [ Script execution time: 0,0487 ]   [ 16 queries used ]   [ Generated: 24.06.23, 22:14 GMT ]  

              Классы исключительных ситуаций именуются начиная с буквы «Е», а базовый класс просто называется Exception. Этот базовый класс содержит необходимую функциональность, которую наследуют все объекты ошибок. Тут можно выделить свойство Message, в котором содержится сообщение об ошибке и функции работы с файлом помощи, через которые можно вызвать файл справки с описанием про­изошедшей ошибки.

              В библиотеке VCL предопределено достаточно большое количество классов на различные типы ошибок, и все они являются наследниками Exception. Например, класс EinOutError соответствует ошибке ввода-вывода. Такие ошибки возникают при обращении к дискам.

              Когда происходит ошибка, то создается объект, который является наследником класса, соответствующего типу ошибке. Так, если произошла ошибка ввода- вывода, то будет создан экземпляр класса EinOutError.

              Давайте рассмотрим пример из листинга 8.10, где в блоке обработки ошибок я пытаюсь разделить число на ноль, что запрещено. Результат деления заносится в переменную t. Обратите внимание, что после этого я делаю проверку if. Эта проверка абсолютно бессмысленна и добавлена только для того, чтобы после деле­ния было хоть какое-то обращение к переменной. Если никакого обращения не бу­дет, то Delphi видит бессмысленность деления и оптимизатор не делает его.

              var

              t,r:Double; begin try r: =0; t:=10/r; if t>0 then exit; except
              // обработка ошибки ввода-вывода

               on EinOutError do begin

              ShowMessage(‘Ошибочка ввода-вывода’); end;

              // обработка деления на ноль

              on е:

              EZeroDivide do begin .

              ShoWMessage(‘Ну нельзя делить на ноль :: ‘+е.Message); end; // Иначе else

              ShowMessage(‘Не понял в чем дело, но что-то произошло’);

              end;

              end;

              В данном случае в блоке except идет два блока обработки разных типов ошибок. Чтобы проверить, не произошла ли ошибка ввода-вывода, пишем следующий блок:

              on [переменная : ] класс_ошибки do begin

              // Ошибка ввода-вывода end;

              Если дословно перевести, что здесь написано, то это будет выглядеть так: в случае ошибки выполнить код между begin и end. Обратите внимание, что пере­менную я заключил в квадратные скобки. Это означает, что переменную заводить не обязательно, что мы и делаем при обработке ошибки ввода-вывода:

              on EInOutError do begin

              Shovfllessage(‘Ошибочка ввода-вывода’); end;

              В случае ошибки вызывается функция showMessage, которая отображает на эк­ране окно диалога с сообщением, которое указано в качестве параметра.

              А теперь посмотрим на то, как мы обрабатываем ошибку деления на ноль:

              on е:EZeroDivide do begin

              ShowMessage(‘Ну нельзя делить на ноль :: ‘+е.Message); end;

              Ошибке деления на ноль соответствует класс EZeroDivide. Перед классом ошибки написана переменная с именем е. Через нее мы сможем узнать сообщение об ошибке, например, так е.Message.

              Помимо этого, в блоке except листинга 8.10 стоит еще ключевое слово else, как при логической операции. Обратите внимание, что после end прямо перед else стоит точка с запятой, хотя мы знаем, что это ее не нужно ставить. Ненужно только для логических операций. В данном случае else используется для обработки ис­ключительных ситуаций, и операция после этого ключевого слова будет выполне­на, если до этого ошибка не была обработана. То есть если произошла ошибка, ко­торая не была обработана блоком on ошибка do, то будет выполнен код после else.

              Итак, попробуйте создать новое приложение, поместить на него кнопку и по ее нажатии написать код из листинга 8.10. Запустите пример и лучше сделайте это из Delphi. Теперь попробуйте нажать на кнопку. Произойдет ошибка, и Delphi пере­хватит на себя управление, покажет строку кода, где произошла исключительная ситуация, и покажет окно диалога с сообщением, описывающим ошибку.

              Осмотрев строку кода, где произошла ошибка, нажимаем клавишу <F9>, чтобы продолжить выполнение программы. И в этот момент управление будет передано нашей программе, и вы увидите сообщение, которое мы показываем с помощью функции ShowMessage В блоке except.

              Если бы вы запустили программу не из Delphi, а из файлового менеджера акти­вировали исполняемый файл, созданный в Delphi, то в момент ошибки вы увидели бы только второе сообщение, которое мы отображаем с помощью функции SenMessage.

              Сообщения могут генерироваться не только исполняемой средой, но и вручную. Чтобы сгенерировать свое сообщение, используется оператор raise. После этого оператора нужно указать объект ошибки. Именно объект, т. е экземпляр какого-то класса ошибки.

              Давайте посмотрим, как можно вручную сгенерировать ошибку ввода-вывода. Чтобы создать новый объект этого класса, нужно вызвать метод create, а этому ме­тоду передается сообщение, которое будет отображаться, когда сработает событие.

              EinOutError.Create(‘Ошибка ввода-вывода’)

              Итак, конструктор create вернет нам экземпляр класса ошибки ввода-вывода. Его мы и должны указать после оператора raise:

              raise EinOutError.Create(‘Ошибка ввода-вывода’);

              Вы можете создать собственный класс ошибки, нарастить его возможности, как душа пожелает, и использовать его. Давайте посмотрим, как это будет выглядеть на примере. Создадим класс MyException, который будет является наследником базо­вого класса всех ошибок — Exception:

              type

              MyException = class(Exception) public

              function GetSomeStrO:String;

              end;

              Это объявление типа, поэтому все это должно быть в разделе type вашего моду­ля. Помимо того что класс наследовал от базового, мы объявили еще одну функ­цию Getsomestr, которая просто возвращает строку. Не будем усложнять жизнь, а реализуем эту функцию банально — просто вернем заранее определенную строку:

              function MyException.GetSomeStr: String;

              begin

              Result:=’Это моя строка’;

              end;

              Теперь поместите на форму кнопку и по ее нажатии напишите следующий код: try

              raise MyException.Create(‘Тест’); except on e:MyException do

              begin

              ShowMessage(e.GetSomeStr);

              end;

              end;

              В разделе try мы вручную генерируем ошибку собственного типа MyException. В разделе except мы перехватываем эту ошибку и с помощью функции ShowMessage отображаем результат функции GetSomeStr. Вот так все просто и красиво.

              Помоги проекту! Расскажи друзьям об этом сайте:

            • Ошибка деление на ноль postgresql
            • Ошибка деление на 0 формула используемая при расчете оклад долянеполногорабочеговремени времявднях
            • Ошибка деление на 0 при увольнении
            • Ошибка декомпрессии при распаковке архива
            • Ошибка декомпрессии метаданных астериос