Форум: "Основная";
Текущий архив: 2002.10.07;
Скачать: [xml.tar.bz2];
ВнизКак в делфи объявить комплексное число Найти похожие ветки
← →
Ionv (2002-09-26 07:21) [0]Нужно решить задачу с комплексными числами, а я незнаю как их объявить. Помогите кто может. СПАСИБО!!!
← →
MBo (2002-09-26 07:25) [1]придется ввести записи или классы с полями RE и IM, и создать соответственно функции для действий с ними или методы. На torry наверняка есть библиотечки.
← →
Esu (2002-09-26 07:35) [2]Вот тут мне всегда хочется сказать ?++, но я не скажу ;)
← →
andrey_pst (2002-09-26 07:37) [3]//////////////////////////////////////
// класс комплексных чисел
type
TComplex = class(TObject)
private
x : integer; // целая часть
y : real; // комплексная часть
public
constructor Create();
...
...
...
Destructor Free();
end;
implementation
constructor TComplex.Create();
befin
Inherited Create();
x := 0;
y := 0;
end;
destructor TComplex.Free();
befin
x := 0;
y := 0;
Inherited;
end;
///////////////////////////////////
// Пользование:
procedure TForm1.Button1Click(Sender: TObject);
var
c : TComplex;
begin
c := TComplex.Create();
// ну вот у тебя есть свой объект - комплексное число
// делай с ним что хочешь
...
...
c.Free;
end;
← →
MBo (2002-09-26 07:42) [4]>andrey_pst
> x : integer; // целая часть
Не целая, а реальная, число в общем случае, конечно,вещественное
> y : real; // комплексная часть
мнимая часть
← →
andrey_pst (2002-09-26 07:48) [5]пардон :)
с утра мозги где-то далеко...
← →
TTCustomDelphiMaster (2002-09-26 09:17) [6]В D6 класс комплексных чисел уже реализован. Только я забыл в каком модуле. Попробуйте провести поиск по словам: complex, compl, real, TComplex...
← →
qube (2002-09-26 09:43) [7]VarComplexCreate
← →
Anatoly Podgoretsky (2002-09-26 09:51) [8]По real не надо :-)
← →
TTCustomDelphiMaster (2002-09-26 10:14) [9]Anatoly Podgoretsky © (26.09.02 09:51)
Почему не надо?
Насколько я помню в этом классе свойство содержащее реальную часть называется Real.
Вы думаете что в исходниках D6 часто встречается Real? И потом если искать с помощью средств Delphi - Search - Find in files, то найти можно за 1 мин.
← →
Юрий Зотов (2002-09-26 10:45) [10]А зачем же целый объект городить? Это же сколько лишнего-то получится... лишняя память, лишний код, создавать, уничтожать, следить за корретностью ссылок... Сплошная головная боль.
А ведь задача этого не требует. Разве record недостаточно?
← →
andrey_pst (2002-09-26 10:52) [11]В смысле - "головная боль" ? Это-ж просто ООП. В Object Pascal куда ни плюнь - объекты.
← →
Юрий Зотов (2002-09-26 11:00) [12]Там, где надо - да, а где не надо - нет. Посмотрите модуль Math, например.
Объект нужен тогда, когда от кода требуется некая активность. А от числа она не требуется, оно само по себе ничего делать не должно, операции проводятся НАД ним, а не им самим. Так ведь можно дойти до того, что и integer сделать объектом. Смысл?
Умная фраза гласит - "не плодите сущностей без необходимости".
← →
qube (2002-09-26 11:18) [13]Позвольте возразить.
Методы классов -- это и есть в первую очередь операции НАД объектом.
← →
TTCustomDelphiMaster (2002-09-26 11:26) [14]Уважаемые коллеги!
У кого есть D6, приведите пожалуйста здесь кусочек кода, в котором объявлен класс комплексного числа. А мы посмотрим почему господа из Borland не сделали его с помощью record.
← →
Separator (2002-09-26 11:35) [15]>TTCustomDelphiMaster
тебе как весь юнит VarCmplx или тока это:
TComplexVariantType = class(TPublishableVariantType, IVarStreamable)
protected
function LeftPromotion(const V: TVarData; const Operator: TVarOp;
out RequiredVarType: TVarType): Boolean; override;
function RightPromotion(const V: TVarData; const Operator: TVarOp;
out RequiredVarType: TVarType): Boolean; override;
function GetInstance(const V: TVarData): TObject; override;
public
procedure Clear(var V: TVarData); override;
function IsClear(const V: TVarData): Boolean; override;
procedure Copy(var Dest: TVarData; const Source: TVarData;
const Indirect: Boolean); override;
procedure Cast(var Dest: TVarData; const Source: TVarData); override;
procedure CastTo(var Dest: TVarData; const Source: TVarData;
const AVarType: TVarType); override;
procedure BinaryOp(var Left: TVarData; const Right: TVarData;
const Operator: TVarOp); override;
procedure UnaryOp(var Right: TVarData; const Operator: TVarOp); override;
function CompareOp(const Left: TVarData; const Right: TVarData;
const Operator: Integer): Boolean; override;
procedure StreamIn(var Dest: TVarData; const Stream: TStream);
procedure StreamOut(const Source: TVarData; const Stream: TStream);
end;
← →
qube (2002-09-26 11:36) [16]В D6 нет класса комплексного числа. Есть подтип Variant, см. модуль VarCmplx
← →
Separator (2002-09-26 11:37) [17]Продолжение:
---
{ TComplexVariantType }
procedure TComplexVariantType.BinaryOp(var Left: TVarData;
const Right: TVarData; const Operator: TVarOp);
begin
if Right.VType = VarType then
case Left.VType of
varString:
case Operator of
opAdd:
Variant(Left) := Variant(Left) + TComplexVarData(Right).VComplex.AsString;
else
RaiseInvalidOp;
end;
else
if Left.VType = VarType then
case Operator of
opAdd:
TComplexVarData(Left).VComplex.DoAdd(TComplexVarData(Right).VComplex);
opSubtract:
TComplexVarData(Left).VComplex.DoSubtract(TComplexVarData(Right).VComplex);
opMultiply:
TComplexVarData(Left).VComplex.DoMultiply(TComplexVarData(Right).VComplex);
opDivide:
TComplexVarData(Left).VComplex.DoDivide(TComplexVarData(Right).VComplex);
else
RaiseInvalidOp;
end
else
RaiseInvalidOp;
end
else
RaiseInvalidOp;
end;
procedure TComplexVariantType.Cast(var Dest: TVarData; const Source: TVarData);
var
LSource, LTemp: TVarData;
begin
VarDataInit(LSource);
try
VarDataCopyNoInd(LSource, Source);
if VarDataIsStr(LSource) then
TComplexVarData(Dest).VComplex := TComplexData.Create(VarDataToStr(LSource))
else
begin
VarDataInit(LTemp);
try
VarDataCastTo(LTemp, LSource, varDouble);
TComplexVarData(Dest).VComplex := TComplexData.Create(LTemp.VDouble, 0);
finally
VarDataClear(LTemp);
end;
end;
Dest.VType := VarType;
finally
VarDataClear(LSource);
end;
end;
procedure TComplexVariantType.CastTo(var Dest: TVarData; const Source: TVarData;
const AVarType: TVarType);
var
LTemp: TVarData;
begin
if Source.VType = VarType then
case AVarType of
varOleStr:
VarDataFromOleStr(Dest, TComplexVarData(Source).VComplex.AsString);
varString:
VarDataFromStr(Dest, TComplexVarData(Source).VComplex.AsString);
else
VarDataInit(LTemp);
try
LTemp.VType := varDouble;
LTemp.VDouble := TComplexVarData(LTemp).VComplex.Real;
VarDataCastTo(Dest, LTemp, AVarType);
finally
VarDataClear(LTemp);
end;
end
else
inherited;
end;
procedure TComplexVariantType.Clear(var V: TVarData);
begin
V.VType := varEmpty;
FreeAndNil(TComplexVarData(V).VComplex);
end;
← →
Separator (2002-09-26 11:39) [18]Продолжение 2:
procedure TComplexVariantType.Clear(var V: TVarData);
begin
V.VType := varEmpty;
FreeAndNil(TComplexVarData(V).VComplex);
end;
function TComplexVariantType.CompareOp(const Left, Right: TVarData;
const Operator: Integer): Boolean;
begin
Result := False;
if (Left.VType = VarType) and (Right.VType = VarType) then
case Operator of
opCmpEQ:
Result := TComplexVarData(Left).VComplex.Equal(TComplexVarData(Right).VComplex);
opCmpNE:
Result := not TComplexVarData(Left).VComplex.Equal(TComplexVarData(Right).VComplex);
else
RaiseInvalidOp;
end
else
RaiseInvalidOp;
end;
procedure TComplexVariantType.Copy(var Dest: TVarData; const Source: TVarData;
const Indirect: Boolean);
begin
if Indirect and VarDataIsByRef(Source) then
VarDataCopyNoInd(Dest, Source)
else
with TComplexVarData(Dest) do
begin
VType := VarType;
VComplex := TComplexData.Create(TComplexVarData(Source).VComplex);
end;
end;
function TComplexVariantType.GetInstance(const V: TVarData): TObject;
begin
Result := TComplexVarData(V).VComplex;
end;
function TComplexVariantType.IsClear(const V: TVarData): Boolean;
begin
Result := (TComplexVarData(V).VComplex = nil) or
TComplexVarData(V).VComplex.IsZero;
end;
function TComplexVariantType.LeftPromotion(const V: TVarData;
const Operator: TVarOp; out RequiredVarType: TVarType): Boolean;
begin
{ TypeX Op Complex }
if (Operator = opAdd) and VarDataIsStr(V) then
RequiredVarType := varString
else
RequiredVarType := VarType;
Result := True;
end;
function TComplexVariantType.RightPromotion(const V: TVarData;
const Operator: TVarOp; out RequiredVarType: TVarType): Boolean;
begin
{ Complex Op TypeX }
RequiredVarType := VarType;
Result := True;
end;
procedure TComplexVariantType.StreamIn(var Dest: TVarData;
const Stream: TStream);
begin
with TReader.Create(Stream, 1024) do
try
with TComplexVarData(Dest) do
begin
VComplex := TComplexData.Create;
VComplex.Real := ReadFloat;
VComplex.Imaginary := ReadFloat;
end;
finally
Free;
end;
end;
procedure TComplexVariantType.StreamOut(const Source: TVarData;
const Stream: TStream);
begin
with TWriter.Create(Stream, 1024) do
try
with TComplexVarData(Source).VComplex do
begin
WriteFloat(Real);
WriteFloat(Imaginary);
end;
finally
Free;
end;
end;
procedure TComplexVariantType.UnaryOp(var Right: TVarData;
const Operator: TVarOp);
begin
if Right.VType = VarType then
case Operator of
opNegate:
TComplexVarData(Right).VComplex.DoNegate;
else
RaiseInvalidOp;
end
else
RaiseInvalidOp;
end;
← →
TTCustomDelphiMaster (2002-09-26 11:41) [19]Separator © (26.09.02 11:39)
Хватит, хватит :)
← →
Separator (2002-09-26 11:43) [20]Как всегда борланд замутит, а потом хрен разберешся, может и правда лучше всего record написать какай-нить
← →
Separator (2002-09-26 11:47) [21]Да кстати там еще есть описание:
type
{ Complex data that the complex variant points to }
TComplexData = class(TPersistent)
............
type
TComplexVarData = packed record
VType: TVarType;
Reserved1, Reserved2, Reserved3: Word;
VComplex: TComplexData;
Reserved4: LongInt;
end;
думаю полное описание не стоит приводить, а то еще как-нить закроют доступ на этот форум :)
← →
TTCustomDelphiMaster (2002-09-26 11:54) [22]qube © (26.09.02 11:36)
Да, наверно так и есть.
Что то с памятью моей стало. Надо меньше пить :)
← →
KSergey (2002-09-26 13:23) [23]
> qube © (26.09.02 11:18)
> Позвольте возразить.
> Методы классов -- это и есть в первую очередь операции НАД
> объектом.
Методы - это операции не ад объектом, а операции объекта над своими данными (над своими объектами, да). Но если я хочу сложить 2 числа - то никакими методами каждого из них я этого не добьюсь.
А над комплексными числами все что нужно - это операции над ними самими. Так что конечно, можно и класс замутить, можно пойти и дальше - класс комплексного числа состряпать из двух классов: TReal и TImplicit (эх, жалко D не поддерживает множественное наследование! вот бы где развернуться!!!). Вот только маленький вопрос: зачем? В чем при этом будет выигрыш? (и Борланд по большому счету тут не авторитет, уж простите. Намутить можно многое, но вот смысл?)
← →
qube (2002-09-26 13:32) [24]KSergey ©
В объектно-ориентированных языках операции, выполняемые над данным объектом, называются методами и входят в определение класса объекта. В C++ они называются функциями-членами. Мы будем использовать эти термины как синонимы.
(с) Гради Буч
А о Борланде я и не вспоминал.
← →
andrey_pst (2002-09-26 13:42) [25]Это все уже похоже на один из споров между сторонниками и противниками ООП.
Ionv наверное "немного удивлен" разгоревшейся полемикой :) - парень-то задал простой вопрос. Ему дали два совета: "класс" или "запись". Пусть выбирает. А каша насчет понятий "класс" и "объект" у программистов сплошь и рядом (у меня тоже бывает:)).
← →
qube (2002-09-26 13:45) [26]andrey_pst ©
Да, вся ветка превратилась в оффтопик.
НО! Дали три совета: класс, запись и Variant.
← →
Mike Kouzmine (2002-09-26 14:01) [27]Для паскаля - record, для C++ - класс. (переопределение операций)
← →
andrey_pst (2002-09-26 14:20) [28]qube ©
Variant - не совет, поскольку по определению Variant-"тормоз" и "не рекомендуется" для постоянного использования :)
← →
const-od (2002-09-26 15:09) [29]Тут кто-то заикался насчёт того, чтобы integer классом сделать. Скажите на милость, кто знает Яву, что в ней Сан сделала? Правильно - int - это контейнер, класс с перегруженными в нём всеми операторами и достаточно удобно, должен заметить: в выражениях исользуем как число, и тут же вызываем методы преобразовния к строке, например. Так что...
← →
qube (2002-09-26 15:38) [30]>Variant - не совет
Вот это круто. TField и т.д., COM, OLE и проч. прочитали и ушли курить. Как же тут быть, если Variant по определению не рекомендуется? И зачем его родили? И зачем бедняги из Borland городили такой большой VarCmplx, если он по определиню не рекомендуется? Иду оплакивать судьбу бедного Variant...
А вообще, прежде чем категорично высказываться, задайте себе вопрос: если рекомендуется/не рекомендуется, то для какой задачи? А если человеку надо написать простое вычисление с комплексными числами, чтобы программа была простой в написании и сопровождении, читабельной и потратить на это меньше времени, скажем?
← →
andrey_pst (2002-09-26 16:22) [31]>> qube
когда писал, так и думал, что про COM вспомнят :)
есть же еще interface и dispinterface, а из всей тройки - OleVariant - самый медленный.
Я не говорил, что Variant не нужен - им пользоваться надо, когда выхода другого нет.
← →
qube (2002-09-26 16:31) [32]andrey_pst ©
Ну, COM -- это так, к слову :). Факт в том, что из-за того, что в Дельфи переопределять операторы сложения и т.д. для классов нельзя, то по читаемости программ с комплексными числами (а этот параметр зачастую важнее производительности) реализация с использованием Variant выигрывает. Что еще надо, если есть такая красота:
Complex Variants are custom Variants that represent complex numbers. The Variant type supports direct manipulation using the addition, subtraction, multiplication, division (but not integer division), and negation operators. They have 5 published properties: Real, Imaginary, Radius, Theta, and FixedTheta. They can be cast to and from integer types, floating point types, string types, TDateTime values, and boolean values. In addition, the VarCmplx unit implements a number of global functions for operating on complex Variants.
← →
andrey_pst (2002-09-26 16:58) [33]>> qube
В контексте данной задачи убедили :)
Было приятно побеседовать.
← →
KSergey (2002-09-27 09:57) [34]
> const-od (26.09.02 15:09)
> Тут кто-то заикался насчёт того, чтобы integer классом сделать.
> Скажите на милость, кто знает Яву, что в ней Сан сделала?
> Правильно - int - это контейнер, класс с перегруженными
> в нём всеми операторами и достаточно удобно, должен заметить:
> в выражениях исользуем как число, и тут же вызываем методы
> преобразовния к строке, например. Так что...
Хорошо, предположим есть разные задачи: сделать читабельную программу и сделать быструю программу. Они не то чтобы противоречивы, но в контексте данной задачи - пожлуй да... На яве никто не будет писать критичных по времени и памяти программ. Не для того она. Потому там все и классы. Да еще и из-за синтаксических и философских особенностей языка, так сказать. И, как верно заметил Mike Kouzmine (26.09.02 14:01) только для Си (в случае выбора только между дельфи и Си) есть ооочень большой смысл определить комплексное число как класс - язык таков, перегрузить операции можно. Да и накладны расходы в С для класса намного меньше - там не поддерживается run-time информация.
> qube © (26.09.02 13:32)
> операции, выполняемые... над данным объектом,
Вот именно над данным. И только над ним одним. И какие же интересно операции вы собираетесь выполнять над комплексным числом? Их ну буквально несколько штук можно придумать, и каждое из них оочень простое. Так есть ли смысл?
← →
Юрий Зотов (2002-09-27 10:17) [35]> Потому там все и классы.
Давно и не раз подтверждена известная фраза: "Лучший способ скомпроментировать хорошую идею - это довести ее до абсурда".
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.10.07;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.019 c