(****************************************************************)
(*                     DATABASE TOOLBOX 4.0                     *)
(*     Copyright (c) 1984, 87 by Borland International, Inc.    *)
(*                                                              *)
(*                        REALCONV                              *)
(*                                                              *)
(*  Purpose: Converts real number formats                       *)
(*                                                              *)
(****************************************************************)
unit RealConv;

interface
type
  { types used to translate between 6 and 8 byte reals }
  ieee       = array[1..8] of byte;
  turbo_real = array[1..6] of byte;
  mant       = array[1..5] of byte;

var
  NullIEEE : IEEE;

procedure IEEEToTurbo(l : ieee; var r : real);

procedure TurboToIEEE(r : real; var long : ieee);

implementation

procedure IEEEToTurbo(l : ieee; var r : real);
var
  i : integer;
  t : turbo_real;
  sign : byte;

begin
  { initialize variables }
  r := 0.0;
  for i := 2 to 5 do
    t[i] := 0;
  i := l[7] + l[8] shl 8;
  if i = $7fff then
  begin
    r := 0.0;
    exit
  end;

  if i = $7ff0 then
  begin
    r := 0.0;
    exit
  end;

  i := (l[8] and $7f) shl 4;          { get 7 highest bits of exponent }
  i := i or ((l[7] and $f0) shr 4);   { get rest of exponent }

  if ((i < 985) or (i > 1061)) and (i <> 0) then
                                         { check to make sure exponent }
  begin                                  { is in legal range }
    exit;
  end;

  i := i - 1023;                         { take out bias }
  t[1] := i + $81;                       { put in new bias }
  sign := l[8] and $80;               { get sign bit }

  { build up most significant byte }

  t[6] := sign + ((l[7] and $0f) shl 3) or ((l[6] and $e0) shr 5);

  {make rest of real number in groups of 5 and 3 }

  for i := 5 downto 2 do
    t[i] := ((l[i+1] and $1f) shl 3) or ((l[i] and $e0) shr 5);

  move(t, r, 6);                         { move it into real variable }
end; { IEEEToTurbo }

procedure TurboToIEEE(r : real; var long : ieee);
{ converts from a 6 byte Turbo Pascal real number to an 8 byte
  IEEE number }
var
  realthing : Turbo_real absolute r;
  ExpVal : integer;

  sign, temp : byte;
  i : integer;

begin
  FillChar(long , SizeOf(long), 0);
  { build up Exponent and sighn of long real }
  sign := realthing[6] and $80;  { get sign bit }
  ExpVal := realthing[1] - $81;
  ExpVal := (ExpVal + 1023) shl 4;
  ExpVal := ExpVal or (sign shl 8);
  long[8] := hi(ExpVal);
  long[7] := lo(ExpVal);

  { make mantissa }
  for i := 6 downto 3 do
  begin
    temp := (realthing[i] and $7f shl 1) or
            (realthing[i - 1] and $80 shr 7);

    { split byte and insert into long real }
    long[i + 1] := long[i + 1] + temp and $f0 shr 4;
    long[i] := long[i] + temp and $f shl 4;
  end;

  { take car of last (incomplete) byte }
  temp := realthing[2] and $7f shl 1;
  long[3] := long[3] + temp and $f0 shr 4;
  long[2] := long[2] + temp and $f shr 4;
end; { TurboToIEEE }

begin
  TurboToIEEE(0.0, NullIEEE);
end.