Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];

Вниз

Равенство для real   Найти похожие ветки 

 
Sandman25 ©   (2004-07-06 12:48) [0]

В процессе обсуждения соседних веток мне пришла в голову глупая мысль.
А зачем вообще авторы Pascal/Delphi ввели операцию = для вещественных типов? Не правильнее ли было ее запретить?

И еще. Зачем нужно было поддерживать операции = и <> для логических операндов? Чтобы люди писали
if Cond = True и if Cond1 <> Cond2 вместо
if Cond и if Cond1 xor Cond2?


 
PVOzerski ©   (2004-07-06 12:51) [1]

IMHO Паскаль делался для обучения, а не для юзанья именно на Intel *86. Там даже не обсуждаются различия между числами с фиксированной и плавающей точкой (ср. в Си тип float, в Паскале - real). Так что формально сравнение на равенство никак не воспретишь, не ломая совершенно стандарт языка.


 
Григорьев Антон ©   (2004-07-06 12:56) [2]


> А зачем вообще авторы Pascal/Delphi ввели операцию = для
> вещественных типов?


С нулём сравнивать иногда бывает очень полезно. Да и ситуации всякие бывают.


> И еще. Зачем нужно было поддерживать операции = и <> для
> логических операндов? Чтобы люди писали
> if Cond = True и if Cond1 <> Cond2 вместо
> if Cond и if Cond1 xor Cond2?


Логический тип является в Паскале перечисляемым, т.е. записывается в виде (False,True). Из-за этого к нему применимы все операции сравнения, в т.ч. и "<" и ">" (при этом False<True). Если просто запретить такие операции, нарушится ортогональность языка, а ортогональный синтаксис легче запоминается. Кроме того, xor вместо <> - это очень неестественно. Я даже на плюсах пишу if (a!=0) вместо if (a) и т.д. - пускай оптимизатор сам разбирается.


 
GuAV ©   (2004-07-06 12:56) [3]


> Зачем нужно было поддерживать операции = и <> для логических
> операндов? Чтобы люди писали
> if Cond = True и if Cond1 <> Cond2 вместо
> if Cond и if Cond1 xor Cond2?

Имхо просто так получилось, что они определены для всех перечисленных.
Cond1 <> Cond2
А вот прикинь: оба LongBool, один LongBool(1), другой LongBool(-1). Учитывая, что LongBool юзается в WinAPI и может принимать и 1 и -1 ситуация реальная.


 
GuAV ©   (2004-07-06 12:58) [4]


> Логический тип является в Паскале перечисляемым, т.е. записывается
> в виде (False,True). Из-за этого к нему применимы все операции
> сравнения, в т.ч. и "<" и ">" (при этом False<True).


> Имхо просто так получилось, что они определены для всех
> перечисленных.

:)


 
Danilka ©   (2004-07-06 13:17) [5]

> А зачем вообще авторы Pascal/Delphi ввели операцию = для
> вещественных типов?

тогда и меньше/больше тоже надо запретить:

var R:Single;
begin
 R:=0.1;
 if R>0.1 then
  Label1.Caption:="Больше"
 else
  Label1.Caption:="Не больше"
end;

:))


 
GuAV ©   (2004-07-06 13:29) [6]

Я долго не мог понять почему не запретили
вызов конструкторов как процедур типа"Form1.Create;"  :)


 
Sandman25 ©   (2004-07-06 14:16) [7]

[1] PVOzerski ©   (06.07.04 12:51)

Логично. Наверное, именно в этом дело.

[2] Григорьев Антон ©   (06.07.04 12:56)

В то же время логический тип нельзя назвать всего лишь одним из перечисляемых типов. Ведь мы не можем написать
if otOne then даже если у нас есть TOrdinalType = (otOne, otTwo);

[3] GuAV ©   (06.07.04 12:56)

Это уже проблемы LongBool (и Widnows), а не паскаля ИМХО.

[5] Danilka ©   (06.07.04 13:17)

:)


 
jack128 ©   (2004-07-06 14:22) [8]


> Я долго не мог понять почему не запретили
> вызов конструкторов как процедур типа"Form1.Create;"  :)
а теперь понял? Проясни, пжлста. Если бы вызов Form1.Create(nil) не чем не отличался от вызова любого другого метода, я бы еше понял, а так, исключение в нем приводит к вызову деструктора. Нафиг это нужно было делать?  В общем я до сих пор этот момент не понял..


 
VMcL ©   (2004-07-06 14:22) [9]

>>Sandman25 ©   (06.07.04 12:48)

>Зачем нужно было поддерживать операции = и <> для логических операндов?

if (a = 0) = (b > 2) then ...

>А зачем вообще авторы Pascal/Delphi ввели операцию = для вещественных типов?

Вещественные числа не обязаны иметь дробную часть:
var
 a: Single;
begin
 a := 1;
 // ...
 if a = 1 then ...
end;


 
GuAV ©   (2004-07-06 14:23) [10]


> Это уже проблемы LongBool (и Widnows), а не паскаля ИМХО.

У носорога плохое зрение. Но при его весе это уже не его проблемы :)

Т.е. не LongBool (и Widnows)

по поводу  [3] - xor оказывается тоже "по умному" для этих. Т.е. проблемы нет. Отныне юзаю xor.


 
GuAV ©   (2004-07-06 14:25) [11]


> а теперь понял? Проясни, пжлста.

Имхо, для вызова из другого конструктора. Всего то.


 
jack128 ©   (2004-07-06 14:28) [12]


> Имхо, для вызова из другого конструктора. Всего то.
а зачем такие особенности с вот этим?

> исключение в нем приводит к вызову деструктора.


 
Sandman25 ©   (2004-07-06 14:29) [13]

[9] VMcL ©   (06.07.04 14:22)

>if (a = 0) = (b > 2) then ...

if not ((a = 0) xor (b > 2)) then

Тогда зачем xor? :)
Он эквивалентен <> для типов с всего 2 возможными значениями

>Вещественные числа не обязаны иметь дробную часть:

А вот это уже нужно проверять через приведение типов.
if Round(A) = 1.
Кстати, как насчет:
A := 1.1;
B := 2.1;
if Frac(A) = Frac(B) then
Можно ли заранее знать, выполнится ли if? Не влезая в дебри машинного представления...


 
GuAV ©   (2004-07-06 15:03) [14]


> > Имхо, для вызова из другого конструктора. Всего то.
> а зачем такие особенности с вот этим?
>
> > исключение в нем приводит к вызову деструктора.

Имхо так было удобнее реализовать. Все равно больше одно раза он вызван не будет.

type
TWhatever = class
public
  constructor Create;
  destructor Destroy; override;
end;

TSomething = class(TWhatever)
public
  constructor CreateSpecial;
end;

constructor TWhatever.Create;
begin
 try
   raise Exception.Create("realy bad thing");
 finally
   ShowMessage("finally - TWhatever.Create");
 end;
end;

constructor TSomething.CreateSpecial;
begin
 try
   Create;
 finally
   ShowMessage("finally - TSomething.CreateSpecial");
 end;
end;

destructor TWhatever.Destroy;
begin
 ShowMessage("TWhatever.Destroy");
 inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 TSomething.CreateSpecial;
end;


 
VMcL ©   (2004-07-06 15:19) [15]

>>Sandman25 ©   (06.07.04 14:29) [13]

>Тогда зачем xor? :)

Тогда зачем ты пишешь "Тогда зачем xor" вместо "D2EEE3E4E020E7E0F7E5EC20786F72"?


 
Sandman25 ©   (2004-07-06 15:22) [16]

[15] VMcL ©   (06.07.04 15:19)

Понятно. По историческим причинам.


 
jack128 ©   (2004-07-06 15:56) [17]


> Имхо так было удобнее реализовать. Все равно больше одно
> раза он вызван не будет.
его удобнее? Одну строчку вставить в асм код?

и пример у тебя не много не тот. При вызове констуктора внутри другого конструктора не происходит вызов _ClassCreate, а вот при вызове Form1.Create управление передается именно туда..

procedure       _ClassCreate;
asm
// код по созданию класса  
 ....

// уничтовение класса если есть подняли исключение
      JMP     _HandleAnyException

       {       destroy the object                                                      }

       MOV     EAX,[ESP+8+9*4]
       MOV     EAX,[EAX].TExcFrame.ConstructedObject
       TEST    EAX,EAX // не знаю, что это такое, но при вызове Form1.Create - этот тест проходится успешно..
       JE      @@skip
       MOV     ECX,[EAX]
       MOV     DL,$81
       PUSH    EAX
       CALL    dword ptr [ECX].vmtDestroy
       POP     EAX
       CALL    _ClassDestroy // уничтожаем объект
@@skip:
       {       reraise the exception   }
       CALL    _RaiseAgain
end;


 
GuAV ©   (2004-07-06 16:06) [18]


> и пример у тебя не много не тот.

When a constructor is called using an object reference (rather than a class reference), it does not create an object. Instead, the constructor operates on the specified object, executing only the statements in the constructor"s implementation, and then returns a reference to the object. A constructor is typically invoked on an object reference in conjunction with the reserved word inherited to execute an inherited constructor.
допиши inherited перед Create - будет тот.


 
VMcL ©   (2004-07-06 16:13) [19]

>>Sandman25 ©   (06.07.04 15:22) [16]

Я имел в виду (удобо)читаемость и понятность кода. Что легче понять:
if (a xor b) or ((y > x - c) xor d) then ...
или
if (a <> b) or ((y > x - c) <> d) then ...
?


 
Sandman25 ©   (2004-07-06 16:16) [20]

[19] VMcL ©   (06.07.04 16:13)

Это дело привычки ИМХО. xor гораздо проще какого-нибудь логарифма, но благодаря тому, что логарифмы учат еще в школе, проблем у начинающих с ними меньше, чем с xor.


 
Sandman25 ©   (2004-07-06 16:17) [21]

[19] VMcL ©   (06.07.04 16:13)

И, честно говоря, я ни разу не встречал в программах использование <> с логическими операндами :)


 
jack128 ©   (2004-07-06 16:25) [22]


> допиши inherited перед Create - будет тот.
да не будет нечего!!
Еще раз
constructor TSomething.CreateSpecial;
begin
try
  {inherited} Create; // в любом случае (есть inherited или нет) управление в _ClassCreate не перейдет
finally
  ShowMessage("finally - TSomething.CreateSpecial");
end;
end;

Ну пройдись отладчиком, если мне не веришь ;-)


 
Игорь Шевченко ©   (2004-07-06 16:36) [23]


> if Cond и if Cond1 xor Cond2?


Кто ж такой оператор на трезвую голову поймет-то ?


 
Sandman25 ©   (2004-07-06 16:39) [24]

[23] Игорь Шевченко ©   (06.07.04 16:36)

См. [20].
Кроме того, мне почему-то кажется, что Вы можете привести пример и гораздо более сложных выражений, которые упростить уже невозможно


 
Игорь Шевченко ©   (2004-07-06 16:42) [25]

Sandman25 ©   (06.07.04 16:39)


> Это дело привычки ИМХО


Это ж насколько надо так себя (и других, если, не дай Аллах, им такой код читать придется) не любить :)
Разумеется, писать так никто не запрещает, даже компилятор, но вот то, что такой код менее читабелен, чем первый вариант, я полагаю, видно невооруженным глазом :)


 
GuAV ©   (2004-07-06 16:45) [26]


> // в любом случае (есть inherited или нет) управление в
> _ClassCreate не перейдет

Может и не перейдет. Но все равно по сути это будет не вызов конструктора для class reference а для object reference. типа Form1.Create(AOwner);
ваще мы имхо чужую ветку флудим, спрои ка лучше в новой.


 
Sandman25 ©   (2004-07-06 16:47) [27]

[25] Игорь Шевченко ©   (06.07.04 16:42)

Наверное, я веду себя как упрямый баран, но я настаиваю, что это дело привычки :)
Пересечение множеств на паскале обозначили *, и никого это не путает, хотя и могло бы. Операцию <> обозначили словом xor, и это тоже никого не путает, просто большинство людей привыкли использовать именно <>.
Кстати, меня дико раздражает, что логические and, or и xor не обозначили как-нибудь вроде logand, logor и logxor. Как в фортране, AFAIR.


 
Игорь Шевченко ©   (2004-07-06 16:50) [28]

Sandman25 ©   (06.07.04 16:47)

> но я настаиваю, что это дело привычки


Так никто ж не спорит. Можно и операторы в одну строку писать - тоже дело привычки :) Лично мне, например, читать такой код было бы неудобно, так как для меня xor - это сложение по модулю 2.


> Пересечение множеств на паскале обозначили *


И это, вообще-то разумно :)


 
Sandman25 ©   (2004-07-06 16:57) [29]

[28] Игорь Шевченко ©   (06.07.04 16:50)

>так как для меня xor - это сложение по модулю 2.

А для меня это проверка на неравенство :) Во всяком случае, с таким подходом мне проще понять конструкцию 1001 xor 0111
Кстати, в десятичной системе
8 xor 5 = 3? Если да, то нужно будет переходить на Вашу позицию :)

>И это, вообще-то разумно :)

Depends. С геометрической интерпретацией, да. С алгебраической,
[1,2,3] * [2,4] = [2] выглядит как полный бред :)


 
DiamondShark ©   (2004-07-06 17:09) [30]


> Sandman25 ©   (06.07.04 16:17) [21]
> [19] VMcL ©   (06.07.04 16:13)
>
> И, честно говоря, я ни разу не встречал в программах использование
> <> с логическими операндами :)

Влёгкую.


procedure TMyClass.SetMyBoolProperty(Value: boolean);
begin
 if FMyBoolProperty <> Value then
   begin
     DoSomethingWithSideEffect();
     FMyBoolProperty := Value;
   end
end;


 
Sandman25 ©   (2004-07-06 17:11) [31]

[30] DiamondShark ©   (06.07.04 17:09)

Ну что тут возразишь :)


 
han_malign ©   (2004-07-06 17:49) [32]

<> vs. xor
- кстати, а мне и в голову до этого не приходило, что импликацию можно писать как <=, а аквивалентность как = - все not or, да not(xor) использовал...

>Пересечение множеств на паскале обозначили *...
>logand, logor и logxor
- ну, допустим, для коньюнкции и дизъюнкции в математике тоже специальные символы есть, вот только в ASCII их включить не озаботились - потому что на печатных машинках не было. А правила раскрытия скобок, для коньюнкции и дизъюнкции, объединения и пересечения - как раз соответсвуют сложению и умножению, так что выбор *, для множеств, вполне обоснован...


 
iZEN ©   (2004-07-06 19:31) [33]

/**Григорьев Антон ©   (06.07.04 12:56) [2]
> А зачем вообще авторы Pascal/Delphi ввели операцию = для
> вещественных типов?
С нулём сравнивать иногда бывает очень полезно. Да и ситуации всякие бывают.
*/
Ну уж с нулём Real всё равно не сравнишь - "не попадёшь".  В этом случае нужно в эпсилон попасть - тогда можно будет считать, что это "как бы нуль".
В Delphi есть определение NaN (not a number), в Java тоже есть.
А как дела обстоят с isNull?

Например, для Java:
Результат выражения Double.NaN == Double.NaN всегда равен false, поэтому приходится пользоваться методом класса-оболочки:
Float.isNaN(знаечение float) и Double.isNaN(знаечение double).

По поводу бесконечности в Java.
1f/0f = Float.POSITIVE_INFINITY
1d/0d = Double.POSITIVE_INFINITY
1f/-0f = Float.NEGATIVE_INFINITY
1d/-0d = Double.NEGATIVE_INFINITY


 
OSokin   (2004-07-06 21:18) [34]

SandMan, а зачем тогда они сделали строку, а не просто массив символов?


 
Sandman25 ©   (2004-07-07 09:25) [35]

[34] OSokin   (06.07.04 21:18)

>SandMan, а зачем тогда они сделали строку, а не просто массив символов?

Это потому что Pascal - строго типизированный ЯП. И дополнительно:
Если речь о String[n], то чтобы ускорить обработку за счет хранения длины.
Если речь о AnsiString, то чтобы не копировать когда не надо, и чтобы была совместимость с PChar.
Если речь об WideString, то чтобы была совместимость с PWideChar.



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 1.685 c
4-1086984795
alienserg
2004-06-12 00:13
2004.07.25
Synchronize внутри DLL. Пытаюсь рисовать из треда на форме.


14-1089192896
Vlad Oshin
2004-07-07 13:34
2004.07.25
Чем прочитать файл? Прислали акт, непойму в чем смотреть.


14-1089217266
ALex191261
2004-07-07 20:21
2004.07.25
Как можно заблокировать клавиатура.


6-1085734986
Phantom
2004-05-28 13:03
2004.07.25
Как пропинговать ряд компьютеров


4-1087044511
Delphins
2004-06-12 16:48
2004.07.25
Как узнать RAS пароли в Delphi?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский