|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 12288 (0x3000) Types: Ada Source Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Interchange_Float, seg_0009ce
└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000 └─ ⟦5a81ac88f⟧ »Space Info Vol 1« └─⟦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;
nblk1=b nid=0 hdr6=16 [0x00] rec0=1d rec1=00 rec2=01 rec3=030 [0x01] rec0=15 rec1=00 rec2=02 rec3=02a [0x02] rec0=1e rec1=00 rec2=03 rec3=00e [0x03] rec0=1f rec1=00 rec2=04 rec3=034 [0x04] rec0=1b rec1=00 rec2=05 rec3=008 [0x05] rec0=1c rec1=00 rec2=06 rec3=030 [0x06] rec0=1c rec1=00 rec2=07 rec3=03e [0x07] rec0=1a rec1=00 rec2=08 rec3=05c [0x08] rec0=1d rec1=00 rec2=09 rec3=002 [0x09] rec0=18 rec1=00 rec2=0a rec3=050 [0x0a] rec0=1d rec1=00 rec2=0b rec3=000 tail 0x2050016347bac64ad0a61 0x42a00088462060003