Интересно, а что же тогда по такой логике NET Standard
?.. Даже страшно подумать.
Там у них всё путано. Через пару лет будет Net 5.0 и там будет одна версия.
Но к сожалению, они не допилили Reflection.Emit, поэтому PascalABC.NET откомпилировать не сможем.
Там нет проблемы, это у serega что-то на компьютере
Как и сказал, Вы даже не его изобретатель. Видал я подобных новаторов на форумах, которые то языки хотят новые написать, переизобретая существующие языковые конструкции, то тех, которые свои OC сотворить желают, да только языком треплют, создавая темы вроде “Супер-пупер крутая программа”… А когда их просят что-то поискать, почитать они отмахиваются мол не хотят искать, либо не могут, либо ещё что-нибудь придумывают (как Вы, например), чтобы предстать перед простым народом новатором. Хотя, эксперты форума всё равно выводят подобных личностей на чистую воду…
Кстати, это паттерн из другого языка и насколько принято выполнять здесь (и в C#
) подобные выкрутасы мне неизвестно. Так что будь я на Вашем месте, я бы сначала детально изучил бы паттерн, а потом бы его применял.
Вторая ссылка - описание и примеры использования.
Мистика, но две версии кода выдают разный результат:
if L<M then L:=M;
if L<mn then L:=mn;
if L<R then L:=R;
L := max(L,M,R,mn)
где искать ошибку? в компиляторе? где реализация max(params int[] values) ???
ага… расследование … PABCSystem.pas, row 8091 Это кто такой добрый и внимательный???
function Max(a, b, c, d: integer): integer;
begin
Result := a;
if b > Result then Result := b;
if c < Result then Result := c; // WTF ????
if d > Result then Result := d;
end;
Нечего искать ошибки в устаревших версиях. В последней уже исправлено.
Только нашел.
У меня официальная сборка с сайта: PascalABC.NET (версия 3.6.2, сборка 2413 от 16.04.2020)
Кстати, почему не сделали через Generic, params & IComporable ?
params
версия есть. Но для маленького кол-ва параметров - Max(a,b,c,d)
выполнится быстрее, потому что массив нигде не создаётся.
А IComparable
вообще хорошая идея.
type
I1 = interface
procedure p1;
end;
r1 = record(I1)
procedure p1;
begin
end;
end;
procedure p1(a: r1);
begin
a.p1;
end;
procedure p2<T>(a: T); where T: I1;
begin
a.p1;
end;
begin
var lc1 := 10000;
var lc2 := 1000000;
var sw1 := new Stopwatch;
var sw2 := new Stopwatch;
var a := new r1;
for var i := 1 to lc1 do
begin
sw1.Start;
loop lc2 do p1(a);
sw1.Stop;
sw2.Start;
loop lc2 do p2(a);
sw2.Stop;
System.Console.Title := (i/lc1).ToString('P');
end;
Writeln(sw1.Elapsed);
Writeln(sw2.Elapsed);
readln;
end.
@Admin разницы по скорости вообще 0. Наверное это потому что когда JIT создаёт версию p2
с определённым типом - он вызывает сразу r1.p1
, а не I1.p1
.
Поэтому если нигде в Max
не преобразовывать в IComparable
, а только вызывать его методы - можно сделать общий Max
, который будет работать и для real
, и для integer
, и сразу для всего остального. Ну и Min
тоже, конечно.
Не понял, что вы хотите. Приведите ровно пример, который вы хотите, и покройте его тестами.
Я полагаю, что-то типа такого:
function Max<T>(a, b: T): T; where T: IComparable<T>;
begin
if b.CompareTo(a) = 1 then Result := b else Result := a;
end;
function Max<T>(a, b, c: T): T; where T: IComparable<T>;
begin
Result := a;
if b.CompareTo(Result) = 1 then Result := b;
if c.CompareTo(Result) = 1 then Result := c;
end;
function Max<T>(a, b, c, d: T): T; where T: IComparable<T>;
begin
Result := a;
if b.CompareTo(Result) = 1 then Result := b;
if c.CompareTo(Result) = 1 then Result := c;
if d.CompareTo(Result) = 1 then Result := d;
end;
function Max<T>(params comparables: array of T): T; where T: IComparable<T>;
begin
if (comparables = nil) or (comparables.Length = 0) then raise new System.ArgumentException();
Result := comparables[0];
for var i := 1 to comparables.Length - 1 do
if comparables[i].CompareTo(Result) = 1 then Result := comparables[i];
end;
Возможно, я не прав.
function _Max<T>(a,b,c,d: T): T; where T: IComparable<T>;
begin
Result := a;
if Result.CompareTo(b)<0 then Result := b;
if Result.CompareTo(c)<0 then Result := c;
if Result.CompareTo(d)<0 then Result := d;
end;
//ToDo так же Max с 2 и 3 параметрами
function Max_<T>(params a: array of T): T; where T: IComparable<T>;
begin
Result := a[0];
for var i := 1 to a.Length-1 do
if Result.CompareTo(a[i])<0 then
Result := a[i];
end;
//ToDo и всё это ещё раз, для Min
begin
_Max(1,2,3,4).Println;
_Max(4,3,2,1).Println;
Max_(1,2,3,4).Println;
Max_(4,3,2,1).Println;
end.
Это много методов, но явно меньше чем вот это вот всё:
///-function Max(a: число, b: число): число;
/// Возвращает максимальное из чисел a,b
function Max(a, b: byte): byte;
///--
function Max(a, b: shortint): shortint;
///--
function Max(a, b: smallint): smallint;
///--
function Max(a, b: word): word;
///--
function Max(a, b: integer): integer;
///--
function Max(a, b: BigInteger): BigInteger;
///--
function Max(a, b: longword): longword;
///--
function Max(a, b: int64): int64;
///--
function Max(a, b: uint64): uint64;
///--
function Max(a, b: real): real;
///-function Min(a: число, b: число): число;
/// Возвращает минимальное из чисел a,b
function Min(a, b: byte): byte;
///--
function Min(a, b: shortint): shortint;
///--
function Min(a, b: word): word;
///--
function Min(a, b: smallint): smallint;
///--
function Min(a, b: integer): integer;
///--
function Min(a, b: BigInteger): BigInteger;
///--
function Min(a, b: longword): longword;
///--
function Min(a, b: int64): int64;
///--
function Min(a, b: uint64): uint64;
///--
function Min(a, b: real): real;
///-function Min(a,b,...: T): T;
/// Возвращает минимальное из a,b,...
function Min<T>(params a: array of T): T;
///--
//function Min(params a: array of real): real;
///--
function Min(a, b, c: real): real;
///--
function Min(a, b, c, d: real): real;
///--
function Min(a, b, c: integer): integer;
///--
function Min(a, b, c, d: integer): integer;
///-function Max(a,b,...: T): T;
/// Возвращает максиимальное из a,b,...
function Max<T>(params a: array of T): T;
///--
//function Max(params a: array of real): real;
///--
function Max(a, b, c: real): real;
///--
function Max(a, b, c, d: real): real;
///--
function Max(a, b, c: integer): integer;
///--
function Max(a, b, c, d: integer): integer;
При этом функционала наоборот больше даёт.
Тесты ошибок - там только знак (>
/<
) перепутать можно, но это уже протестировано теми 4 строчками в begin-end.
Тесты скорости - я уже показал предыдущим сообщением, что это НЕ медленнее, чем писать отдельные Min
и Max
для каждого типа.
Может я чего то не знаю… Разве есть какая-либо гарантия что .CompareTo
всегда будет возвращать только -1, 0 и +1? Да и, в конце концов, пользовательские типы…
Ну заменить на > 0 тогда
Дело не в медленнее. Min(1,2.5,3) - обобщённый метод не сможет вызваться. Тип T не выведется.
Ну тогда оставить перегрузку для real, а вместо Max(a,b: byte, smallint, word, shortint, longword, integer, int64, uint64) сделать методы приведенные выше, кода все равно поубавится
Тут дело такое, что прежде чем говорить об ошибке (они есть, конечно же, в каждой сборке что-то, да меняется, правда, не всегда именно ошибка исправляется, есть и замены, добавления), обязательно надо скачать самую новую версию и проверить на ней.