Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Lazarus, Free Pascal, CodeTyphon
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.12.2017, 10:59   #1
Elock
Пользователь
 
Регистрация: 27.11.2017
Сообщений: 15
Вопрос калькулятор - первый раз делит, а второй раз не хочет и при этом он возвращает начальную число.

У меня теперь появился другой вопрос по поводу калькулятора, я сделал все что надо на него для полной рабочей состоянии, но я нашёл 1 ошибку всё таки...

У меня знаки не очень правильно работают. Когда я хочу делить: первый раз делит, а второй раз не хочет и при этом он возвращает начальную число. К примеру если я делаю 4\2, то будет 2, а если нажать второй раз то будет 4.

Вот сам код:
Код:
Код:
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button_0: TButton;
    Button_Comma: TButton;
    Button_Plus: TButton;
    Button_Eq: TButton;
    Button_Minus: TButton;
    Button_6: TButton;
    Button_9: TButton;
    Button_CE: TButton;
    Button_C: TButton;
    Button_Sqrt: TButton;
    Button_Divide: TButton;
    Button_1: TButton;
    Button_Multiply: TButton;
    Button_Pow: TButton;
    Button_Log: TButton;
    Button_2: TButton;
    Button_3: TButton;
    Button_4: TButton;
    Button_7: TButton;
    Button_BK: TButton;
    Button_8: TButton;
    Button_5: TButton;
    Ecran: TEdit;
    Ecran_Prev: TEdit;
    Memo1: TMemo;
    procedure Button_LogClick(Sender: TObject);
    procedure Button_PowClick(Sender: TObject);
    procedure Button_SqrtClick(Sender: TObject);
    procedure Button_CClick(Sender: TObject);
    procedure Button_CEClick(Sender: TObject);
    procedure Button_BKClick(Sender: TObject);
    procedure Button_EqClick(Sender: TObject);
    procedure ClickBut(Sender: TObject);
    procedure ClickZnak(Sender: TObject);
    procedure ClickComma(Sender :TObject);
    procedure FormShow(Sender: TObject);
    procedure Memo1DblClick(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    procedure display_ecran(numb: integer; number: Real);
    function  get_ecran(numb: integer):Real;
    function  transform_numb(number : Real):String;
    function  transform_screen(ecran_text : String):Real;
  end;

var
  Form1: TForm1;
  a, b, c : Real;
  mem : Real;
  znak : string;
  oper : string;


implementation

{$R *.lfm}

{ TForm1 }

function TForm1.transform_numb(number : Real):String;
begin
  try
      Memo1.Lines.Add('transform_numb:'+FloatToStr(number));
      result := FloatToStr(number);
  except
      result := '0';
  end;
end;

function  TForm1.transform_screen(ecran_text : String):Real;
begin
  try
      Memo1.Lines.Add('transform_screen:'+ecran_text);
      result := StrToFloat(ecran_text);
  except
      result := 0;
  end;
end;


procedure TForm1.display_ecran(numb: integer; number: Real);
begin
   Memo1.Lines.Add('display_ecran['+IntToStr(numb)+']:'+transform_numb(number));
   if numb=1 then
      Ecran.Text := transform_numb(number)
   else
      Ecran_Prev.Caption := transform_numb(number)
end;


function TForm1.get_ecran(numb: integer):Real;
begin
   if numb=1 then
   begin
      Memo1.Lines.Add('get_ecran[1]:'+Ecran.Text);
      result := transform_screen(Ecran.Text);
   end
   else
   begin
      Memo1.Lines.Add('get_ecran[2]:'+Ecran_Prev.Caption);
      result := transform_screen(Ecran_Prev.Caption);
   end;
end;

procedure TForm1.ClickZnak(Sender: TObject);
begin
  Memo1.Lines.Add(oper+':znak');
  oper := 'znak';
  a := get_ecran(1);
  display_ecran(2, a);
  b := 0;
  display_ecran(1, b);

  znak := (sender as TButton).Caption;

end;

procedure TForm1.ClickComma(Sender: TObject);
var
    str : string;
begin
  Memo1.Lines.Add(oper+':comma');
  if oper = 'comma' then
     exit;

  oper := 'comma';

  str := transform_numb(get_ecran(1))+'.';
  display_ecran(1, transform_screen(str));

  if Ecran.Text = '0' then
     Ecran.Text := '0';
  Ecran.Text := Ecran.Text + (Sender as TButton).Caption;

end;

procedure TForm1.FormShow(Sender: TObject);
begin
    Memo1.Lines.Add(oper+':empty');
    oper := 'empty';
    Ecran.Text := '0';
    Ecran_Prev.Text := '';
    a := 0;
    b := 0;
    c := 0;
end;

procedure TForm1.Memo1DblClick(Sender: TObject);
begin
    Memo1.Clear;
end;

procedure TForm1.Button_BKClick(Sender: TObject);
var
    str : string;
begin
    Memo1.Lines.Add(oper+':backspace');
    oper := 'backspace';
    str := Ecran.Text;
    if str <> '' then
        Delete(str, Length(str),1);

    if str = '' then
        str := '0';

    Ecran.Text:= str;
end;

procedure TForm1.ClickBut(Sender: TObject);
begin
    Memo1.Lines.Add(oper+':number - '+(Sender as TButton).Caption);
    oper := 'number';

    if length(Ecran.Text) > 15 then
        exit;

    if Ecran.Text = '0' then
        Ecran.Text := '';
    Ecran.Text := Ecran.Text + (Sender as TButton).Caption;
end;

procedure TForm1.Button_SqrtClick(Sender: TObject);
begin
    oper := 'oper';
    Memo1.Lines.Add(oper+':oper');
    a := StrToFloat(Ecran.Text);
    a := sqrt(a);
    Ecran.Text := FloatToStr(a);
    a := 0;
end;

procedure TForm1.Button_LogClick(Sender: TObject);
begin
    Memo1.Lines.Add(oper+':oper');
    oper := 'oper';
    a := StrToFloat(Ecran.Text);
    if a<>0 then
        begin
            a:= 1 / (a);
            Ecran.Text:=floattostr(a);
        end
    else
        begin
            Ecran.Text:='Error';
        end;

    Ecran.Text := FloatToStr(a);
    a := 0;
end;

procedure TForm1.Button_PowClick(Sender: TObject);
begin
    Memo1.Lines.Add(oper+':oper');
    oper := 'oper';
    a := StrToFloat(Ecran.Text);
    a := sqr(a);
    Ecran.Text := FloatToStr(a);
    a := 0;
end;

procedure TForm1.Button_CClick(Sender: TObject);
begin
    Memo1.Lines.Add(oper+':clear');
    oper := 'clear';
    Ecran.Text := '0';
end;

procedure TForm1.Button_CEClick(Sender: TObject);
begin
    Memo1.Lines.Add(oper+':clearall');
    oper := 'clearall';
    Ecran.Text := '0';
    Ecran_Prev.Text := '';
    a := 0;
    b := 0;
    c := 0;
end;

procedure TForm1.Button_EqClick(Sender: TObject);
begin
   b := StrToFloat(Ecran.Text);
   Ecran.Clear;

    Memo1.Lines.Add(oper+':equal-'+znak);
    oper := 'equal';
    display_ecran(2, a);
    c := 0;
    case znak of
        '+' : c := a + b;
        '-' : c := a - b;
        '*' : c := a * b;
        '/' : begin
                  if b<>0 then
                      c := a / b;
              end;
    end;
    display_ecran(1, c);

end;

end.
_____
Код программы нужно выделять (форматировать) тегами [CODE] (читать FAQ)
Модератор

Последний раз редактировалось Elock; 13.12.2017 в 18:12.
Elock вне форума Ответить с цитированием
Старый 14.12.2017, 07:36   #2
ildar_50
Новичок
Джуниор
 
Регистрация: 12.05.2009
Сообщений: 1
По умолчанию Делим 4 на 2 и еще раз на 2....

Правильный ответ 4. Напишите на листке бумаги трехэтажную обыкновенную дробь 4/2/2. 2 уходит в числитель 2 и 2 сокращаются. Ответ 4.

На VB6.0 код простой и доступен для учащихся 9 классов. Решая Ваш пример, дает ответ 1, как бы Вы и хотели. Вот код:





Public x As Double
Public f As Integer
Public y As Timer


Private Sub Command1_Click()
Form2.Show
End Sub


Private Sub Command2_Click()
Text1.Text = Text1.Text + ","
End Sub

Private Sub Form_Load()
Label1.Caption = Date


End Sub

Private Sub mnuCos_Click()
Text1.Text = Cos(Text1.Text)
End Sub

Private Sub mnuExit_Click()
Unload Me
End Sub

Private Sub mnuSin_Click()
Text1.Text = Sin(Text1.Text)
End Sub

Private Sub mnuSqr_Click()
Text1.Text = (Text1.Text) * (Text1.Text)
End Sub

Private Sub mnuSqrt_Click()
Text1.Text = Sqr(Text1.Text)
End Sub

Private Sub mnuTan_Click()
Text1.Text = Tan(Text1.Text)
End Sub

Private Sub mnuUnset_Click()
Text1.Text = ""
End Sub

Private Sub Command10_Click()
Text1.Text = Text1.Text + "4"
End Sub



Private Sub Command11_Click()
Text1.Text = Text1.Text + "5"
End Sub

Private Sub Command12_Click()
Text1.Text = Text1.Text + "6"
End Sub

Private Sub Command13_Click()
Text1.Text = Text1.Text + "1"
End Sub

Private Sub Command14_Click()
Text1.Text = Text1.Text + "2"
End Sub

Private Sub Command15_Click()
Text1.Text = Text1.Text + "3"
End Sub
Private Sub Command16_Click()

Text1.Text = Text1.Text + "0"
End Sub













Private Sub mnuSubtract_Click()
x = Val(Text1.Text)
Text1.Text = ""
f = 2
End Sub 'Запоминание числа в текстовом поле после нажатия кнопки "-", очистка текстового поля и установка "флага" равным 2.

Private Sub mnuMultiply_Click()
x = Val(Text1.Text)
Text1.Text = ""
f = 3
End Sub 'Запоминание числа в текстовом поле после нажатия кнопки "*", очистка текстового поля и установка "флага" равным 3.

Private Sub mnuSeparate_Click()
x = Val(Text1.Text)
Text1.Text = ""
f = 4
End Sub 'Запоминание числа в текстовом поле после нажатия кнопки "/", очистка текстового поля и установка "флага" равным 4.

Private Sub mnuIs_Click()
If f = 1 Then Text1.Text = Val(Text1.Text) + x
If f = 2 Then Text1.Text = x - Val(Text1.Text)
If f = 3 Then Text1.Text = Val(Text1.Text) * x
If f = 4 And Val(Text1.Text) <> 0 Then Text1.Text = x / Val(Text1.Text)
If f = 4 And Val(Text1.Text) = 0 Then Text1.Text = "Деление на 0"
End Sub



Private Sub Command7_Click()
Text1.Text = Text1.Text + "7"
End Sub

Private Sub Command8_Click()
Text1.Text = Text1.Text + "8"
End Sub

Private Sub Command9_Click()
Text1.Text = Text1.Text + "9"
End Sub




Private Sub mnuSumma_Click()
x = Val(Text1.Text)
Text1.Text = ""
f = 1
End Sub




Private Sub Timer1_Timer()
Label2.Caption = Time

Label3.Caption = WeekdayName(DatePart("w", Date, vbMonday))

End Sub

Последний раз редактировалось ildar_50; 14.12.2017 в 08:00. Причина: конкретизация ответа.
ildar_50 вне форума Ответить с цитированием
Старый 14.12.2017, 12:51   #3
Elock
Пользователь
 
Регистрация: 27.11.2017
Сообщений: 15
По умолчанию

Вроде я всё понял, но что в твоём коде означает Text1.Text????

Но честно как-то подозрительный код + его тяжело довольно читать :с

Последний раз редактировалось Elock; 14.12.2017 в 12:55.
Elock вне форума Ответить с цитированием
Старый 14.12.2017, 13:36   #4
Sciv
Старожил
 
Аватар для Sciv
 
Регистрация: 16.05.2012
Сообщений: 3,211
По умолчанию

Цитата:
Сообщение от Elock Посмотреть сообщение
но что в твоём коде означает Text1.Text??
То же, что и у Вас:

Код:
  Ecran.Text
Конкретно по ошибке: Вы а и b после деления не меняете, соответственно при повторном клике будет выполняться не операция (c/b) или (a/b)/b, а операция a/(b/b) - об этом Вам уже написали.

Ну и так, пара рекомендаций:

1) логику лучше не мешать с UI и выносить в отдельный модуль. В Вашем случае все вычисления можно было бы оформить в виде функций, описать в отдельном модуле и вызывать из модуля формы.
2) пишите юнит-тесты на логику, это помогает чинить баги на этапе разработки.
3) пользуйтесь дебагом и прочими инструментами трассировки кода, чтобы локализовать место возникновения ошибки.
4) избавляйтесь от глобальных переменных везде, где это возможно. Если есть класс - вынесите их в секцию private класса. Или вообще лучше объявлять их внутри тех процедур/функций, где они используются.
Начал решать проблему с помощью регулярных выражений. Теперь решаю две проблемы...

Последний раз редактировалось Sciv; 14.12.2017 в 13:51.
Sciv вне форума Ответить с цитированием
Старый 14.12.2017, 20:24   #5
Elock
Пользователь
 
Регистрация: 27.11.2017
Сообщений: 15
По умолчанию

Цитата:
Сообщение от Sciv Посмотреть сообщение
То же, что и у Вас:

Код:
  Ecran.Text
Конкретно по ошибке: Вы а и b после деления не меняете, соответственно при повторном клике будет выполняться не операция (c/b) или (a/b)/b, а операция a/(b/b) - об этом Вам уже написали.

Ну и так, пара рекомендаций:

1) логику лучше не мешать с UI и выносить в отдельный модуль. В Вашем случае все вычисления можно было бы оформить в виде функций, описать в отдельном модуле и вызывать из модуля формы.
2) пишите юнит-тесты на логику, это помогает чинить баги на этапе разработки.
3) пользуйтесь дебагом и прочими инструментами трассировки кода, чтобы локализовать место возникновения ошибки.
4) избавляйтесь от глобальных переменных везде, где это возможно. Если есть класс - вынесите их в секцию private класса. Или вообще лучше объявлять их внутри тех процедур/функций, где они используются.


У меня вопрос где именно ошибка,а не какие программы где выдаються ошибки o_O

Просто подскажи где мне надо изменить код......

Код:
Ecran.Text
Тут даже каждый поймёт, что это главный экран у калькулятора, ведь у калькулятора же 1...
Elock вне форума Ответить с цитированием
Старый 15.12.2017, 09:54   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Elock Посмотреть сообщение
Когда я хочу делить: первый раз делит, а второй раз не хочет и при этом он возвращает начальную число. К примеру если я делаю 4\2, то будет 2, а если нажать второй раз то будет 4.
а почему речь идёт только про команду деления?
а команды + - * при повторном нажатии разве работают?!


Цитата:
Сообщение от Elock Посмотреть сообщение
Просто подскажи где мне надо изменить код......
в процедуре Button_EqClick

И выложите архив с исходниками проекта.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 15.12.2017, 19:50   #7
Elock
Пользователь
 
Регистрация: 27.11.2017
Сообщений: 15
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
а почему речь идёт только про команду деления?
а команды + - * при повторном нажатии разве работают?!



в процедуре Button_EqClick

И выложите архив с исходниками проекта.
Обясни как это сделать и я сделаю с:
Точнее как сюда кинуть этот архив
Elock вне форума Ответить с цитированием
Старый 15.12.2017, 23:18   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Elock Посмотреть сообщение
Точнее как сюда кинуть этот архив
запаковать исходники в архив, перейти на форум, на форме ответ нажать на кнопку "Загрузить файлы", "Управление вложениями" - указать имя файл через "Обзор", потом "загрузить файл". всё.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 18.12.2017, 21:29   #9
Elock
Пользователь
 
Регистрация: 27.11.2017
Сообщений: 15
По умолчанию

Блин превышает норма мегабайтов на форуме :с
Elock вне форума Ответить с цитированием
Старый 18.12.2017, 23:33   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Это Вы три дня архив запаковывали? Не быстро...

Цитата:
Сообщение от Elock Посмотреть сообщение
Блин превышает норма мегабайтов на форуме :с
во-первых, запакуйте в архив только файлы с расширением *.pas, *.lfm, *.lpr, *.lpi
архив получится ОЧЕНЬ маленький.

во-вторых, на крайний случай, если весь тот stuff, что Вы засунули в архив (включая EXE файлы, отладочную информацию, сохранённые версии и прочая), привёл к тому, что архив стал огромным и не проходит на форум - можно его выложить на любой файлообменни или в облачное хранилище. Ну, например, disk.yandex.ru.
или http://rgho.st или любой другой.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дан ряд любых чисел. Когда повторяется число второй раз, то его надо удалить. Katia1234 Помощь студентам 6 05.05.2012 10:09
первый раз в VBA ГОСЕАН Помощь студентам 0 23.04.2012 04:41
этот код первый раз то окно сначала сворачивается, а потом сразу восстанавливается, а когда вызываешь второй, окно сворачивается? Аlex Общие вопросы Delphi 4 16.08.2008 11:51