type

  fx32r = packed record
    case integer of
    0: (i: longint);
    1: (ifrac: word; iint: smallint);
  end;

  fx64r = packed record
    case integer of
    0: (i: int64);
    1: (ifrac: dword; iint: longint);
  end;


  operator := (f: fixed32) s: single;
  begin
    s:= f.i / 65536.0;
  end;

{  operator := (f: fixed64) s: single;
  begin
    s:= f.i / (65536.0 * 65536.0)
  end;
}
  operator := (f: fixed32) d: double;
  begin
    d:= f.i / 65536.0;
  end;

{  operator := (f: fixed64) d: double;
  begin
    d:= f.i / (65536.0 * 65536.0)
  end;
}
  operator := (s: single) f: fixed32;
  begin
    Assert(not MotherState^.FloatToFixedAssignmentsDisabled, 'Float to Fixed assignment attempted while it''s forbidden to');
    f.i:= Round(s*65536.0);
  end;

  operator := (d: double) f: fixed32;
  begin
    Assert(not MotherState^.FloatToFixedAssignmentsDisabled, 'Float to Fixed assignment attempted while it''s forbidden to');
    f.i:= Round(d*65536.0);
  end;
{
  operator := (s: single) f: fixed64;
  begin
    Assert(not MotherState^.FloatToFixedAssignmentsDisabled, 'Float to Fixed assignment attempted while it''s forbidden to');
    f.i:= Round(s*65536.0*65536.0);
  end;

  operator := (d: double) f: fixed64;
  begin
    Assert(not MotherState^.FloatToFixedAssignmentsDisabled, 'Float to Fixed assignment attempted while it''s forbidden to');
    f.i:= Round(d*65536.0*65536.0);
  end;
 }


  operator := (f: fixed32) i: int64;
  begin
    i:= int64(f.i) div 65536;
  end;
  operator := (f: fixed32) i: qword;
  begin
    i:= qword(f.i) div 65536;
  end;
  operator := (f: fixed32) i: longint;
  begin
    i:= f.i div 65536;
  end;
  operator := (f: fixed32) i: dword;
  begin
    i:= dword(f.i) div 65536;
  end;
  operator := (f: fixed32) i: smallint;
  begin
    i:= f.i div 65536;
  end;
  operator := (f: fixed32) i: word;
  begin
    i:= f.i div 65536;
  end;
  operator := (f: fixed32) i: shortint;
  begin
    i:= f.i div 65536;
  end;
  operator := (f: fixed32) i: byte;
  begin
    i:= f.i div 65536;
  end;

  operator := (i: int64) f: fixed32;
  begin
    f.i:= i shl 16;
  end;
  operator := (i: qword) f: fixed32;
  begin
    f.i:= i shl 16;
  end;
  operator := (i: longint) f: fixed32;
  begin
    f.i:= i shl 16;
  end;

  operator := (i: dword) f: fixed32;
  begin
    f.i:= i shl 16;
  end;

  operator := (i: smallint) f: fixed32;
  begin
    f.i:= longint(i) shl 16;
  end;

  operator := (i: word) f: fixed32;
  begin
    f.i:= dword(i) shl 16;
  end;

  operator := (i: shortint) f: fixed32;
  begin
    f.i:= longint(i) shl 16;
  end;

  operator := (i: byte) f: fixed32;
  begin
    f.i:= dword(i) shl 16;
  end;


  operator * (a, b: fixed32) z: fixed32;
  begin
    z.i:= (int64(a.i)*int64(b.i)) shr 16;
  end;

  operator * (a, b: fixed64) z: fixed64;
  begin
    fx64r(z).ifrac:= (int64(fx64r(b).ifrac) * int64(fx64r(a).ifrac)) shr 32;
    fx64r(z).iint:= int64(fx64r(a).iint) * int64(fx64r(b).iint);
    z.i+= int64(fx64r(a).ifrac) * int64(fx64r(b).iint) + int64(fx64r(b).ifrac) * int64(fx64r(a).iint);
  end;

  operator / (a, b: fixed32) z: fixed32;
  begin
    z.i:= (int64(fx32r(a).iint) shl 16) div int64(b.i);
  end;

  operator / (a, b: fixed64) z: fixed64;
  var onedivb: fixed64;
  begin
    onedivb.i:= (int64($4000000000000000 {1.0 in 32.32 shl 30}) div b.i) shl 2; //losing 2 bits of precision
    z:= a * onedivb; //see the multiplication operator defined above
  end;


  function fixed64.sin(): fixed64;
  begin

  end;

  function fixed64.cos(): fixed64;
  begin

  end;

  function fixed64.sqr(): fixed64;
  begin

  end;

  function fixed64.sqrt(): fixed64;
  begin

  end;





  function fixed32.sin(): fixed32;
  begin

  end;

  function fixed32.cos(): fixed32;
  begin

  end;

  function fixed32.sqr(): fixed32;
  begin
    i:= (int64(i) * int64(i)) shr 32;
  end;

  function fixed32.sqrt(): fixed32;
  begin

  end;




  function fixedFake.sin(): single;
  begin
    Result:= system.sin(f);
  end;

  function fixedFake.cos(): single;
  begin
    Result:= system.cos(f);
  end;

  function fixedFake.sqr(): single;
  begin
    Result:= system.sqr(f);
  end;

  function fixedFake.sqrt(): single;
  begin
    Result:= system.sqrt(f);
  end;






  operator + (a, b: fixed32) z: fixed32;
  begin
    z.i:= a.i + b.i;
  end;

  operator - (a, b: fixed32) z: fixed32;
  begin
    z.i:= a.i - b.i;
  end;

  operator = (a, u: fixed32) b: System.boolean;
  begin
    b:= a.i = u.i;
  end;

  operator < (a, u: fixed32) b: System.boolean;
  begin
    b:= a.i < u.i;
  end;

  operator > (a, u: fixed32) b: System.boolean;
  begin
    b:= a.i > u.i;
  end;

  operator >= (a, u: fixed32) b: System.boolean;
  begin
    b:= a.i >= u.i;
  end;

  operator <= (a, u: fixed32) b: System.boolean;
  begin
    b:= a.i <= u.i;
  end;

  function FixedToStr(Value: fixed32): string;
  begin
    Result:= FloatToStr(Value.i / 65536.0);
  end;
  function FixedToStr(Value: fixed32; const FormatSettings: TFormatSettings): string;
  begin
    Result:= FloatToStr(Value.i / 65536.0, FormatSettings);
  end;




