Математика и Delphi delphid.dax.ru WinSov.com Редкая программа обходится без простейших алгебраических действий: "плюс", "минус", "разделить", "умножить" - их Delphi понимает и заботливо выделяет синим цветом. Но позже начинаются трудности. Стоит вам прописать что-то вроде Edit1.Text:= 'Координаты окна: ' + Form1.Left, + ', ' + Form1.Top, как компилятор выдает сообщение: "Incompatible types: String and Integer". Что же это за типы и почему они несовместимы? Информация может быть различной: текстовой, графической, цифровой, в десяти,- восьми,- шестнадцатеричной и т.п. системах. Чтобы корректно воспринимать ее, в Delphi, да и во всех других языках, введены переменные, или типы (types). В примере выше мы столкнулись с двумя из них, наиболее распространенными. String - буквально "строка", текстовая информация. Integer - простое число в диапазоне -2147483648…2147483647. Хотя из ведра в сито перелить нельзя, добрый Borland предоставил нам функции для перевода из одного типа в другой (из модуля SysUtils.pas): Function IntToStr(Value: Integer): String; Function StrToInt(Const S: String): Integer; Обратите внимание на возвращаемые значения функций. Наш пример должен выглядеть так: Edit1.Text:= 'Координаты окна: ' + IntToStr(Form1.Left), + ', ' + IntToStr(Form1.Top); Form1.Top:=StrToInt(Edit2.Text); Посмотрите на вторую строчку кода. Значение Edit2.Text должно быть ТОЛЬКО числовым, иначе вы получите сообщение об ошибке. А если нужно работать с иррациональными числами, например, с числом "пи"? Для таких данных существует свой тип: real. Переменной такого типа можно присвоить значение параметра integer без всяких промежуточных функций, но наоборот сделать нельзя. А чтобы увязать real с текстом, существуют команды: Function FloatToStr(Value: Extended): String; Function StrToFloat(Const S: String): Extended; тоже из модуля SysUtils.pas. (Поэтому не забывайте декларировать этот модуль при создании консольного приложения с математическими действиями.) Пропишите что-нибудь вроде Edit1.Text:=FloatToStr(pi), чтобы оценить возможности переменной real. С её помощью можно уже производить более серьезные вычисления, например, возведение в квадрат посредством функции Sqr(x: real) и извлечение квадратного корня: Sqrt(x: real), что в модуле System.pas. Там же можно найти функции Sin и Cos с аналогичными параметрами. Там, где синус с косинусом, должен быть тангенс и какой-никакой секонс, которые и присутствуют в виде функций Tan, Cotan, Cosecant, Sec, ArcSin, ArcCos, ArcCot, ArcSec и прочая в модуле Math.pas. Модуль этот незаменим также, если вы хотите возвести число в степень. Function Power(const Base: extended; const Exponent: Extended):extended, где Base - число, которое возводиться в степень, Exponent - показатель степени. Form1.Caption:=Power(2,3); //возведение числа 2 в куб Вот еще некоторые сокровища модуля Math: Hypot - вычисление гипотенузы по длине катетов; RadToDeg, DegToRad - преобразование радианов в градусы и наоборот; Floor - округление в меньшую строну; Ceil - округление в большую сторону; SinCos - вычисление синуса и косинуса; Mean - среднее арифметическое в комбинации чисел. (Например: Caption:=FloatToStr(Mean([10,10,2])) - находит среднее арифметическое трех данных чисел, но, конечно же, искомых чисел может быть и больше, и меньше указанных в примере трех.) Часто бывает, что нужно прочертить прямую точно по центру Image1, что невозможно сделать делением параметра Image1.Width на два, поскольку в итоге почти всегда получается иррациональное real-число. Мы воспользуемся командой div, вычисляющей результат деления - целое число - без остатка. Image1.Canvas.MoveTo(Image1.Width div 2, 0); Image1.Canvas.LineTo(Image1.Width div 2, Image1.Height); В настоящем примере ширина полотна Image1 делится без остатка на два. Обратите внимание, что делитель пишется не в скобках, а сразу после команды div. Как написать на Delphi генератор случайных чисел? Командой Random, после которой в скобках указывается максимальная величина генерируемого числа. Edit1.Text:=IntToStr(Random(100)); //генератор случайных чисел в пределах ста А сейчас мы применим наши математические познания и создадим утилиту для решения квадратных уравнений вида: ax2+bx+c ? 0 Если вы учились в школе, то помните, что эти уравнения имеют два корня, которые находятся по формуле х1,2 = (-b±2^(b^2+4ac))/2a Да, страшная формула… На форму бросайте компоненты TRichEdit, два Button'a - CountButton и ExitButton - и три LabeledEdit'а, в которые вводятся, соответственно, параметры a, b, c. Найдите у LabeledEdit'ов свойство LabelPosition и поставьте его в lpLeft. Мы будем работать с параметрами a, b, с и дискриминантом (для тех, кто не знает, - сумма квадрата b и учетверенного произведения a и c). В Delphi таких переменных нет, мы сами их придумали, а потому нужно продекларировать их в var. Удерживая нажатой клавишу Shift, выберите все три LabeledEdit'a и по событию OnKeyPress поставьте у всех LabeledEdit1KeyPress (и далее см. листинг): procedure TForm1.LabeledEdit1KeyPress(Sender: TObject; var Key: Char); begin if not (Key in ['0'..'9','-', Char(VK_BACK)]) then begin //вводить можно только числа Beep; Key:=#0; end; end; procedure TForm1.CloseButtonClick(Sender: TObject); begin Application.Terminate; //гарантированно освобождает память - в отличие от Close end; procedure TForm1.CountButtonClick(Sender: TObject); var a, b, c, diskrim, x1, x2: real; begin //если а=0 - прерываем процесс if (LabeledEdit1.Text='0') or (LabeledEdit1.Text=EmptyStr) then abort; //если данные не введены - ставим 0 if LabeledEdit2.Text=EmptyStr then LabeledEdit2.Text:='0'; if LabeledEdit3.Text=EmptyStr then LabeledEdit3.Text:='0'; //инициализируем переменные a:=StrToFloat(LabeledEdit1.Text); b:=StrToFloat(LabeledEdit2.Text); c:=StrToFloat(LabeledEdit3.Text); //находим дискриминант diskrim:=Sqr(b) + 4*a*c; if diskrim < 0 then begin //если он меньше нуля, уравнение не имеет смысла RichEdit1.Clear; RichEdit1.Lines.Add('D<0. Корней нет!'); Abort; //прерываем процесс end; b:=b*-1; //х1 и х2 a:=a*2; x1:=(b + Sqrt(diskrim))/a; x2:=(b - Sqrt(diskrim))/a; //выводим результаты RichEdit1.Clear; RichEdit1.Lines.Add('Решение:' + #10 + #10 + 'Находим дискриминант: D = ' + FloatToStr(Diskrim) + #10); if diskrim > 0 then RichEdit1.Lines.Add('D>0. Уравнение имеет 2 корня.'+ #10 + 'x1=' + FloatToStr(x1) + '; x2=' + FloatToStr(x2)); if diskrim = 0 then RichEdit1.Lines.Add('D=0. Уравнение имеет 1 корень.' + #10 + 'x=' + FloatToStr(x1)); end; Ну вот мы и познакомились, с некоторыми математическими возможностями Delphi