Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2010-04

Help creating generic class: division problem

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

leledumbo

consider the following generic class declaration:

{$mode objfpc}{$H+}
type
  generic TMedian<T> = class
    class function Find(x: array of T): T;
  end;
class function TMedian.Find(x: array of T): T;
var
  i, j, Middle: Integer;
  Temporary: T;
begin
  // Use truncated selection sort to find median
  Middle := (High(x) + 1) div 2;
  for i := 0 to Middle do
    for j := 1 to High(x) - i do
      if x[j] > x[j - 1] then begin
        Temporary := x[j];
        x[j] := x[j - 1];
        x[j - 1] := Temporary;
      end;
  if Odd(High(x)) then
    // When High(x) is Odd, there are an even number of elements in array.
    // Define median as average of two middle values.
    Result := (x[Middle] + x[Middle - 1]) / 2 // <-- This line
  else
    // When High(x) is Even, there are an odd number of elements in array.
    // Median is the middle value.
    Result := x[Middle];
end {Find};

How can I make it work such that:

type
  TMedianInteger = specialize TMedian<Integer>;
  TMedianDouble = specialize TMedian<Double>;

is valid?

See the line marked with <-- above, due to semantic of /, I can't use integer because / returns floating point value, Extended to be precise. If I change it to div, it won't work (correctly) for floating point values, because the precision is lost. Typecasting to T won't work either because Extended can't be converted to LongInt (larger to smaller type problem).

View this message in context: http://old.nabble.com/Help-creating-generic-class%3A-division-problem-tp28140305p28140305.html Sent from the Free Pascal - General mailing list .

Reply by email

Martin
to leledumbo

If it is only between int and double, maybe this will help have on overload function

class function TMedian.Div(Value, Divider: Integer): Integer; // Result
:= Value div Divider
class function TMedian.Div(Value, Divider: Double): Double; //  Result
:= Value / Divider

then the compiler chooses dependent on T.

leledumbo wrote 48 lines
consider the following generic class declaration: {$mode objfpc}{$H+} type generic TMedian<T> = class class function Find(x: array of T): T; end; class function TMedian.Find(x: array of T): T; var i, j, Middle: Integer; Temporary: T; begin // Use truncated selection sort to find median Middle := (High(x) + 1) div 2; for i := 0 to Middle do for j := 1 to High(x) - i do if x[j]> x[j - 1] then begin Temporary := x[j]; x[j] := x[j - 1]; x[j - 1] := Temporary; end; if Odd(High(x)) then // When High(x) is Odd, there are an even number of elements in array. // Define median as average of two middle values. Result := (x[Middle] + x[Middle - 1]) / 2 //<-- This line else // When High(x) is Even, there are an odd number of elements in array. // Median is the middle value. Result := x[Middle]; end {Find}; How can I make it work such that: type TMedianInteger = specialize TMedian<Integer>; TMedianDouble = specialize TMedian<Double>; is valid? See the line marked with<-- above, due to semantic of /, I can't use integer because / returns floating point value, Extended to be precise. If I change it to div, it won't work (correctly) for floating point values, because the precision is lost. Typecasting to T won't work either because Extended can't be converted to LongInt (larger to smaller type problem).

Reply by email