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 - 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;