|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: B T
Length: 10534 (0x2926)
Types: TextFile
Names: »B«
└─⟦5f3412b64⟧ Bits:30000745 8mm tape, Rational 1000, ENVIRONMENT 12_6_5 TOOLS
└─⟦91c658230⟧ »DATA«
└─⟦458657fb6⟧
└─⟦a5bbbb819⟧
└─⟦this⟧
└─⟦d10a02448⟧ Bits:30000409 8mm tape, Rational 1000, ENVIRONMENT, D_12_7_3
└─⟦fc9b38f02⟧ »DATA«
└─⟦9b46a407a⟧
└─⟦eec0a994f⟧
└─⟦this⟧
package body Interchange_Float is
use Interchange_Defs;
Radix : constant := 2 ** 8;
subtype Long_Integer is Interchange_Defs.Longest_Integer;
subtype Long_Natural is Long_Integer range 0 .. Long_Integer'Last;
subtype Exponent_Type is Long_Integer range -127 .. 128;
subtype Fraction_Type is Long_Integer range 0 .. (2 ** 23) - 1;
subtype Long_Exponent_Type is Long_Integer range -1023 .. 1024;
subtype Long_Fraction_Type is Long_Integer range 0 .. (2 ** 52) - 1;
function Find_Exponent (Data : Interchange_Defs.Long_Float)
return Long_Exponent_Type is
-- Return the (unbiased) exponent part of an IEEE float.
-- The DATA must be > 0.0.
-- The exponent must be > exponent'first.
-- The answer is found by binary search.
Answer : Long_Exponent_Type;
Temp : Long_Integer;
procedure Binary_Search is
Step : Long_Exponent_Type;
begin
Step := abs (Answer) / 2;
while Step /= 0 loop
if (Answer < Long_Exponent_Type'Last) and then
Data >= (2.0 ** Standard.Integer (Answer + Step)) then
Answer := Answer + Step;
else
-- Take some care to avoid numeric_error:
if Answer < Long_Exponent_Type'Last then
if Data < (2.0 ** Standard.Integer
(Answer - Step + 1)) then
Answer := Answer - Step;
end if;
else
if (Data / 2.0) < (2.0 ** Standard.Integer
(Answer - Step)) then
Answer := Answer - Step;
end if;
end if;
-- Both alternatives really do the same thing, but they're
-- set up so they don't produce intermediate results which
-- would be out of range.
end if;
Step := Step / 2;
end loop;
end Binary_Search;
begin
pragma Assert (Data > 0.0);
if Data >= 2.0 then
Answer := 1;
while Data >= (2.0 ** Standard.Integer (Answer + 1)) loop
Answer := 2 * Answer;
exit when Answer >= Long_Exponent_Type'Last;
-- Long_Exponent_Type'Last is a power of 2.
end loop;
Binary_Search;
elsif Data < 1.0 then
Answer := -1;
while Data < (2.0 ** Standard.Integer (Answer)) loop
Temp := 2 * Long_Integer (Answer);
if Temp < Long_Exponent_Type'First then
exit;
else
Answer := Long_Exponent_Type (Temp);
end if;
-- Long_Exponent_Type'First is not a power of 2.
end loop;
Binary_Search;
else
Answer := 0;
end if;
return Answer;
end Find_Exponent;
function Convert (X : Interchange_Float.Float)
return Interchange_Defs.Float is
Bytes : Interchange_Float.Float := X;
Data : Interchange_Defs.Float;
Negative : Boolean := False;
Exponent : Exponent_Type := 0;
Fraction : Fraction_Type := 0;
Biased_Exponent : Natural;
begin
declare
use Byte_Defs; -- byte operations
begin
if "/=" ((Bytes (1) / 128), 0) then
Negative := True;
Bytes (1) := Bytes (1) mod 128;
end if;
Biased_Exponent := (Natural (Bytes (1)) * 2)
+ (Natural (Bytes (2)) / 128);
Bytes (2) := Bytes (2) mod 128;
for I in 2 .. 4 loop
Fraction := (Fraction * Fraction_Type (Radix))
+ Fraction_Type (Bytes (I));
end loop;
end;
Exponent := Exponent_Type (Biased_Exponent - 127);
if Exponent = 128 then
Data := Interchange_Defs.Float'Last;
elsif Exponent > -127 then
Data :=
(1.0 + (Interchange_Defs.Float (Fraction) * (2.0 ** (-23))))
* (2.0 ** Standard.Integer (Exponent));
elsif Fraction /= 0 then
Data := (Interchange_Defs.Float (Fraction) * (2.0 ** (-23)))
* (2.0 ** (-126));
else
Data := 0.0;
end if;
if Negative then
Data := -Data;
end if;
return Data;
end Convert;
function Convert (X : Interchange_Defs.Float)
return Interchange_Float.Float is
Data : Interchange_Defs.Float := X;
Bytes : Interchange_Float.Float;
Negative : Boolean := False;
Exponent : Exponent_Type;
Fraction : Fraction_Type;
Biased_Exponent : Long_Natural;
begin
if Data < 0.0 then
Negative := True;
Data := -Data;
end if;
if Data = 0.0 then
Exponent := Exponent_Type'First;
Fraction := 0;
elsif Data < (2.0 ** (-126)) then
Exponent := Exponent_Type'First;
Data := Data * (2.0 ** 126);
Fraction := Fraction_Type (Data * (2.0 ** 23));
elsif Data > (2.0 - (2.0 ** (-23))) * (2.0 ** 127) then
Exponent := Exponent_Type'Last;
Fraction := 0;
else
Exponent := Exponent_Type (Find_Exponent
(Interchange_Defs.Long_Float
(Data)));
Data := Data * (2.0 ** Standard.Integer (-Exponent));
Fraction := Fraction_Type ((Data - 1.0) * (2.0 ** 23));
end if;
Biased_Exponent := Exponent + 127;
for I in reverse 2 .. 4 loop
Bytes (I) := Byte_Defs.Byte (Fraction mod Fraction_Type (Radix));
Fraction := Fraction / Fraction_Type (Radix);
end loop;
if Biased_Exponent mod 2 /= 0 then
Bytes (2) := Byte_Defs."+" (Bytes (2), 128);
end if;
Bytes (1) := Byte_Defs.Byte (Biased_Exponent / 2);
if Negative then
Bytes (1) := Byte_Defs."+" (Bytes (1), 128);
end if;
return Bytes;
end Convert;
function Convert (X : Interchange_Float.Long_Float)
return Interchange_Defs.Long_Float is
Data : Interchange_Defs.Long_Float;
Bytes : Interchange_Float.Long_Float := X;
Negative : Boolean := False;
Exponent : Long_Exponent_Type := 0;
Fraction : Long_Fraction_Type := 0;
Biased_Exponent : Natural;
begin
declare
use Byte_Defs; -- byte operations
begin
-- get sign bit:
if "/=" ((Bytes (1) / 128), 0) then
Negative := True;
Bytes (1) := Bytes (1) - 128;
end if;
-- get biased exponent:
Biased_Exponent := (Natural (Bytes (1)) * 16)
+ (Natural (Bytes (2)) / 16);
-- get fraction:
Fraction := Long_Fraction_Type (Bytes (2)) mod 16;
for I in 3 .. 8 loop
Fraction := (Fraction * Long_Fraction_Type (Radix))
+ Long_Fraction_Type (Bytes (I));
end loop;
end;
Exponent := Long_Exponent_Type (Biased_Exponent - 1023);
if Exponent = 1024 then
Data := Interchange_Defs.Long_Float'Last;
elsif Exponent > -1023 then
Data := (1.0 + (Interchange_Defs.Long_Float (Fraction) *
(2.0 ** (-52))))
* (2.0 ** Standard.Integer (Exponent));
elsif Fraction /= 0 then
Data := (Interchange_Defs.Long_Float (Fraction) * (2.0 ** (-52)))
* (2.0 ** (-1022));
else
Data := 0.0;
end if;
if Negative then
Data := -Data;
end if;
return Data;
end Convert;
function Convert (X : Interchange_Defs.Long_Float)
return Interchange_Float.Long_Float is
Data : Interchange_Defs.Long_Float := X;
Bytes : Interchange_Float.Long_Float;
Negative : Boolean := False;
Exponent : Long_Exponent_Type;
Fraction : Long_Fraction_Type;
Biased_Exponent : Long_Natural;
begin
if Data < 0.0 then
Negative := True;
Data := -Data;
end if;
if Data = 0.0 then
Exponent := Long_Exponent_Type'First;
Fraction := 0;
elsif Data < (2.0 ** (-1022)) then
Exponent := Long_Exponent_Type'First;
Data := Data * (2.0 ** 1022);
Fraction := Long_Fraction_Type (Data * (2.0 ** 52));
elsif Data > (2.0 - (2.0 ** (-52))) * (2.0 ** 1023) then
Exponent := Long_Exponent_Type'Last;
Fraction := 0;
else
Exponent := Long_Exponent_Type (Find_Exponent (Data));
Data := Data * (2.0 ** Standard.Integer (-Exponent));
Fraction := Long_Fraction_Type
((Data - 1.0) * (2.0 ** 52));
end if;
Biased_Exponent := Exponent + 1023;
-- put fraction:
for I in reverse 2 .. 8 loop
Bytes (I) := Byte_Defs.Byte
(Fraction mod Long_Fraction_Type (Radix));
Fraction := Fraction / Long_Fraction_Type (Radix);
end loop;
-- put biased exponent:
Bytes (2) := Byte_Defs."+"
(Bytes (2), Byte_Defs.Byte
(16 * (Biased_Exponent mod 16)));
Bytes (1) := Byte_Defs.Byte (Biased_Exponent / 16);
-- put sign bit:
if Negative then
Bytes (1) := Byte_Defs."+" (Bytes (1), 128);
end if;
return Bytes;
end Convert;
end Interchange_Float;