[Back to NUMBERS SWAG index] [Back to Main SWAG index] [Original]
{
:>I am looking for a routine that can convert the Extended
:>type to and from a real type without the need to use
:>$N+,$E+ in TP. I have got to read a file containing
:In the back of the TP 6.0 and BP 7.0 manuals, it lists the data format for
:the Extended and Real data types. Conversion should be relatively easy from
:Real to Extended, just a few shifts, as the extended mantissa /exponent
:parts are both larger than the corresponding ones for the Real data type.
:For the same reason, conversion to extended from real will be tricky, as the
:value may not be within the range of a real.
: If I remember correctly, the extended type has a 63-bit mantissa, 1 sign
: bit, and a 16-bit exponent. The real type has an 8-bit exponent, 1 sign bit,
: and a 39-bit mantissa.
From: erwink@xs1.xs4all.nl (erwink)
Seems to work. Here is the result of this hard work:
}
unit convert;
{ converts extended type to real without coprocessor support
or emulation (so can be compiled with $N-,$E-).
Extended is represented by an array of 10 bytes.
}
Interface
type
b10 = array[1..10] of byte;
function Extended2Real(x:b10; var r:real) : boolean;
{ converts 10 byte array containing an extended to a real }
{ returns TRUE if ok, FALSE if overflow }
procedure Real2Extended(r:real; var x:b10);
{ converts real to 10 byte array containing an extended }
implementation
const
signmask : byte = $80;
not_signmask : byte = $7F;
type
b2 = array[1..2] of byte;
ff = record
case integer of
1 : (r : real);
2 : (a : array[1..6] of byte);
end;
function Extended2Real(x : b10; var r : real) : boolean;
var
exp2 : b2;
exponent : integer;
sign : boolean;
i : boolean;
m : ff;
begin
{ extract sign bit and clear it }
sign := (x[10] and signmask) <> 0;
x[10] := x[10] and not_signmask;
{ extract exponent }
exp2[1] := x[9];
exp2[2] := x[10];
exponent := integer(exp2)-16383;
{ extract this funny number i and clear it }
i := (x[8] and signmask) <> 0;
x[8] := x[8] and not_signmask;
{ if i is not set then we had a denormalized number so
return 0 }
if not i then begin
r := 0.0;
Extended2Real := true;
exit;
end;
{ extract mantissa }
m.a[6] := x[8];
m.a[5] := x[7];
m.a[4] := x[6];
m.a[3] := x[5];
m.a[2] := x[4];
{ plug in exponent }
exponent := exponent +129;
if (exponent > 255) then begin
Extended2Real := false;
exit;
end;
if (exponent < 0) then begin
{ underflow }
r := 0.0;
Extended2Real := True;
exit;
end;
m.a[1] := exponent;
{ set sign bit }
if sign then
m.r := -m.r;
r := m.r;
Extended2Real := true;
end;
procedure real2extended(r : real; var x : b10);
var
sign : boolean;
rr : ff absolute r;
exp2 : b2;
exponent : integer;
i : integer;
begin
{ treat 0 specially }
if (r=0.0) then begin
for i := 1 to 10 do
x[i] := 0;
exit;
end;
{ extract sign bit and set it }
sign := (rr.a[6] and signmask) <> 0;
rr.a[6] := rr.a[6] or signmask;
{ copy mantissa }
x[8] := rr.a[6];
x[7] := rr.a[5];
x[6] := rr.a[4];
x[5] := rr.a[3];
x[4] := rr.a[2];
x[3] := 0;
x[2] := 0;
x[1] := 0;
{ copy exponent }
exp2[2] := 0;
exp2[1] := rr.a[1];
exponent := integer(exp2)+16254;
exp2 := b2(exponent);
{ plug in sign bit }
exp2[2] := exp2[2] and not_signmask;
if sign then
exp2[2] := exp2[2] or signmask;
x[10] := exp2[2];
x[9] := exp2[1];
end;
end.
[Back to NUMBERS SWAG index] [Back to Main SWAG index] [Original]