Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

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

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

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

У меня теперь появился другой вопрос по поводу калькулятора, я сделал все что надо на него для полной рабочей состоянии, но я нашёл 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 в 19:12.
Elock вне форума   Ответить с цитированием
Старый 14.12.2017, 08:36   #2
ildar_50
Новичок
 
Регистрация: 12.05.2009
Сообщений: 1
Репутация: 10
По умолчанию Делим 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 в 09:00. Причина: конкретизация ответа.
ildar_50 вне форума   Ответить с цитированием
Старый 14.12.2017, 13:51   #3
Elock
Пользователь
 
Регистрация: 28.11.2017
Сообщений: 15
Репутация: 10
По умолчанию

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

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

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

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

Код:

  Ecran.Text

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

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

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

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

Цитата:
Сообщение от 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, 10:54   #6
Serge_Bliznykov
МегаМодератор
СуперМодератор
 
Регистрация: 09.01.2008
Сообщений: 23,419
Репутация: 5187
По умолчанию

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


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

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

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



в процедуре Button_EqClick

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

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

Блин превышает норма мегабайтов на форуме :с
Elock вне форума   Ответить с цитированием
Старый 19.12.2017, 00:33   #10
Serge_Bliznykov
МегаМодератор
СуперМодератор
 
Регистрация: 09.01.2008
Сообщений: 23,419
Репутация: 5187
По умолчанию

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

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

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

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

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


10:57.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru