![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как в делфи объявить комплексное число [D6, Win95/98]
Ionv © (2002-09-26 07:21:00)Нужно решить задачу с комплексными числами, а я незнаю как их объявить. Помогите кто может. СПАСИБО!!!
Юрий Зотов (2002-09-27 10:17:00) [1]> Потому там все и классы.
Давно и не раз подтверждена известная фраза: "Лучший способ скомпроментировать хорошую идею - это довести ее до абсурда".
KSergey (2002-09-27 09:57:00) [2]
> const-od (26.09.02 15:09)
> Тут кто-то заикался насчёт того, чтобы integer классом сделать.
> Скажите на милость, кто знает Яву, что в ней Сан сделала?
> Правильно - int - это контейнер, класс с перегруженными
> в нём всеми операторами и достаточно удобно, должен заметить:
> в выражениях исользуем как число, и тут же вызываем методы
> преобразовния к строке, например. Так что...
Хорошо, предположим есть разные задачи: сделать читабельную программу и сделать быструю программу. Они не то чтобы противоречивы, но в контексте данной задачи - пожлуй да... На яве никто не будет писать критичных по времени и памяти программ. Не для того она. Потому там все и классы. Да еще и из-за синтаксических и философских особенностей языка, так сказать. И, как верно заметил Mike Kouzmine (26.09.02 14:01)только для Си (в случае выбора только между дельфи и Си) есть ооочень большой смысл определить комплексное число как класс - язык таков, перегрузить операции можно. Да и накладны расходы в С для класса намного меньше - там не поддерживается run-time информация.
> qube © (26.09.02 13:32)
> операции, выполняемые... над данным объектом,
Вот именно над данным. И только над ним одним. И какие же интересно операции вы собираетесь выполнять над комплексным числом? Их ну буквально несколько штук можно придумать, и каждое из них оочень простое. Так есть ли смысл?
andrey_pst (2002-09-26 16:58:00) [3]>> qube
В контексте данной задачи убедили :)
Было приятно побеседовать.
qube (2002-09-26 16:31:00) [4]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:22:00) [5]>> qube
когда писал, так и думал, что про COM вспомнят :)
есть же еще interface и dispinterface, а из всей тройки - OleVariant - самый медленный.
Я не говорил, что Variant не нужен - им пользоваться надо, когда выхода другого нет.
qube (2002-09-26 15:38:00) [6]>Variant - не совет
Вот это круто. TField и т.д., COM, OLE и проч. прочитали и ушли курить. Как же тут быть, если Variant по определению не рекомендуется? И зачем его родили? И зачем бедняги из Borland городили такой большой VarCmplx, если он по определиню не рекомендуется? Иду оплакивать судьбу бедного Variant...
А вообще, прежде чем категорично высказываться, задайте себе вопрос: если рекомендуется/не рекомендуется, то для какой задачи? А если человеку надо написать простое вычисление с комплексными числами, чтобы программа была простой в написании и сопровождении, читабельной и потратить на это меньше времени, скажем?
const-od (2002-09-26 15:09:00) [7]Тут кто-то заикался насчёт того, чтобы integer классом сделать. Скажите на милость, кто знает Яву, что в ней Сан сделала? Правильно - int - это контейнер, класс с перегруженными в нём всеми операторами и достаточно удобно, должен заметить: в выражениях исользуем как число, и тут же вызываем методы преобразовния к строке, например. Так что...
andrey_pst (2002-09-26 14:20:00) [8]qube ©
Variant - не совет, поскольку по определению Variant-"тормоз" и "не рекомендуется" для постоянного использования :)
Mike Kouzmine (2002-09-26 14:01:00) [9]Для паскаля - record, для C++ - класс. (переопределение операций)
qube (2002-09-26 13:45:00) [10]andrey_pst ©
Да, вся ветка превратилась в оффтопик.
НО! Дали три совета: класс, запись и Variant.
andrey_pst (2002-09-26 13:42:00) [11]Это все уже похоже на один из споров между сторонниками и противниками ООП.
Ionv наверное "немного удивлен" разгоревшейся полемикой :) - парень-то задал простой вопрос. Ему дали два совета: "класс" или "запись". Пусть выбирает. А каша насчет понятий "класс" и "объект" у программистов сплошь и рядом (у меня тоже бывает:)).
qube (2002-09-26 13:32:00) [12]KSergey ©
В объектно-ориентированных языках операции, выполняемые над данным объектом, называютсяметодами и входят в определение класса объекта. В C++ они называются функциями-членами. Мы будем использовать эти термины как синонимы.
(с) Гради Буч
А о Борланде я и не вспоминал.
KSergey (2002-09-26 13:23:00) [13]
> qube © (26.09.02 11:18)
> Позвольте возразить.
> Методы классов -- это и есть в первую очередь операции НАД
> объектом.
Методы - это операции не ад объектом, а операции объекта над своими данными (над своими объектами, да). Но если я хочу сложить 2 числа - то никакими методами каждого из них я этого не добьюсь.
А над комплексными числами все что нужно - это операции над ними самими. Так что конечно, можно и класс замутить, можно пойти и дальше - класс комплексного числа состряпать из двух классов: TReal и TImplicit (эх, жалко D не поддерживает множественное наследование! вот бы где развернуться!!!). Вот только маленький вопрос: зачем? В чем при этом будет выигрыш? (и Борланд по большому счету тут не авторитет, уж простите. Намутить можно многое, но вот смысл?)
TTCustomDelphiMaster (2002-09-26 11:54:00) [14]qube © (26.09.02 11:36)
Да, наверно так и есть.
Что то с памятью моей стало. Надо меньше пить :)
Separator (2002-09-26 11:47:00) [15]Да кстати там еще есть описание:
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;
думаю полное описание не стоит приводить, а то еще как-нить закроют доступ на этот форум :)
Separator (2002-09-26 11:43:00) [16]Как всегда борланд замутит, а потом хрен разберешся, может и правда лучше всего record написать какай-нить
TTCustomDelphiMaster (2002-09-26 11:41:00) [17]Separator © (26.09.02 11:39)
Хватит, хватит :)
Separator (2002-09-26 11:39:00) [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;
Separator (2002-09-26 11:37:00) [19]Продолжение:
---
{ 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;
qube (2002-09-26 11:36:00) [20]В D6 нет класса комплексного числа. Есть подтип Variant, см. модуль VarCmplx