|
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: 5633 (0x1601) Types: TextFile Names: »B«
└─⟦5f3412b64⟧ Bits:30000745 8mm tape, Rational 1000, ENVIRONMENT 12_6_5 TOOLS └─ ⟦91c658230⟧ »DATA« └─⟦458657fb6⟧ └─⟦1472c4407⟧ └─⟦this⟧ └─⟦d10a02448⟧ Bits:30000409 8mm tape, Rational 1000, ENVIRONMENT, D_12_7_3 └─ ⟦fc9b38f02⟧ »DATA« └─⟦9b46a407a⟧ └─⟦2e03b931c⟧ └─⟦this⟧
separate (Generic_Elementary_Functions) -- On input, Y is a Common_Float number such that -- |Y| <= 2**( Common_Float'Mantissa / 2 ). -- On return, the sum R1 and R2 represents the reduced -- argument (with respect to pi/2) to at least 3/2 of the precision -- offered by Common_Float. Precisely -- -- | R2 | <= Common_Float'Epsilon * | R1 |, -- -- there is an integer value k such that -- -- Y - k( pi/2 ) = (1 + delta) * ( R1 + R2 ), -- | delta | <= (Common_Float'Epsilon) ** (3/2), -- -- and -- -- | R1 + R2 | <= (pi/4) * ( 1 + sqrt(Common_Float'Epsilon) ). -- -- -- There are two major steps in the algorithm. -- -- First, the value k is obtained by -- k := round-to-nearest-integer( Y * Two_by_Pi ), -- where Two_by_Pi is the working-precise value of (2/pi). -- Because the magnitude of Y is never too large, the value k -- obtained is very accurate. Moreover, note also that the value -- k need not be identical to the integer closest to to -- Y*(2/pi), provided that -- Y - k * (pi/2) -- can be computed accurately and that value is small in magnitude -- ( <= pi/4 roughly ). -- -- Second, the difference Y - k*(pi/2) is calculated. In this -- program, (pi/2) is represented by -- pi/2 = Piby2_Piece(1) + Piby2_Piece(2) + ... + -- -- Piby2_Piece( N_Pieces_of_Piby2 ) -- -- in a way such that k * Piby2_Piece(J) is exact for all -- possible J's. Thus, to compute the reduced argument accurately, -- we need only subtract correctly: -- -- Y - k*Piby2_Piece(1) - k*Piby2_Piece(2) - ... -- ... - k*Piby2_Piece( N_Pieces_of_Piby2 ). -- -- Three steps are needed to perform the subtraction. -- -- Step 1. Let X := Y. For J = 1, 2, ...., perform -- X := X - k * Piby2_Piece( J ) -- as long as the subtraction is exact. That is the case if -- (k*Piby2_Piece(J))/2 <= X <= 2*(k*Piby2_Piece(J)). -- -- Step 2. Suppose Step 1 terminates at J = N. Then, -- X = Y - k*(Piby2_Piece(1) + ... + Piby2_Piece(N)) -- exactly. It can be shown that -- X - k*Piby2_Piece(N+1) -- can be represented exactly as -- X - k*Piby2_Piece = X_Lead + X_Trail, -- where -- | X_Trail | <= Common_Float'Epislon * | X_Lead |. -- -- Step 3. At this stage, X_Lead is the reduced argument -- to the precision of Common_Float. We must now calculate -- correction to X_Lead+X_Trail so that the reduced argument -- can be (3/2) the accuracy of Common_Float. Therefore, we -- modify X_Trail by -- X_Trail := X_Trail - k*( Piby2_Piece(N+2) + ... -- + Piby2_Piece( good enough ) ). -- procedure Kp_Pi2rd (Y : in Common_Float; R1, R2 : out Common_Float; I_Flag : out Quadrant_Flag) is X, X_Lead, X_Trail, X_Extra, Temp, F, K, K_Mod16, P, Two_P, Half_P : Common_Float; J, L1, L2 : Integer; Sign_Y : Quadrant_Flag; Same_Sign : Boolean; Tmp_R1 : Common_Float; Two_By_Pi : constant := 16#A.2F983_6E4E4_41529_FC275_7D1F5_34DDC_0DB63#E-1; begin -- Initialization X := Y; Sign_Y := 0; if X < 0.0 then X := -X; Sign_Y := 1; end if; -- Calculation of integer quotient K K := Round (X * Two_By_Pi); K_Mod16 := K * 16#0.1#; K_Mod16 := Truncate (K_Mod16); K_Mod16 := K - 16.0 * K_Mod16; I_Flag := Quadrant_Flag (Integer (K_Mod16) mod 4); if K = 0.0 then R1 := Y; R2 := 0.0; I_Flag := 0; return; end if; -- Step 1. Calcuate X := X - k*Piby2_Piece(J) whenever exact -- Initialization of Step 1 J := 1; P := K * Piby2_Piece (J); Two_P := P + P; Half_P := P * 2#1.0#E-1; -- The loop while X >= Half_P and X <= Two_P and J <= N_Pieces_Of_Piby2 - 2 loop if P > X then X := (X - Half_P) - Half_P; else X := X - P; end if; J := J + 1; P := K * Piby2_Piece (J); Two_P := P + P; Half_P := P * 2#1.0#E-1; end loop; -- End of Step 1 -- Step 2. Represent X - k*Piby2_Piece( J ) in two pieces P := -K * Piby2_Piece (J); X_Lead := X + P; if X < 0.0 then Same_Sign := True; else Same_Sign := False; end if; if abs (X) < abs (P) then Temp := X; X := P; P := Temp; end if; -- Ideally, if the arithmetic of the underlying machine is good, -- X_Trail := (X - X_Lead) + P suffices for our purpose because -- X - X_Lead must be exact. Unforturnately, there are machines -- without a guard bit for subtraction. The trick below ensures -- that (X-F), (X_Lead-F), and (X-F) - (X_Lead-F) are all exact. -- For a detailed explanation of why this trick work, refer to -- pages 10-3 to 10-9 of the notes IMPLEMENTATION OF ALGORITHMS -- by W. Kahan. This set of notes can be obtained through NTIS -- in Virginia. Order number AD769 124 / LP, 1986. F := 0.0; if Same_Sign then F := (0.46 * X_Lead - X_Lead) + X_Lead; end if; X_Trail := ((X - F) - (X_Lead - F)) + P; -- Step 3. Calcuate to higher precision. J := J + 1; L1 := 2 * 4 * Common_Float'Base'Digits - N_Bits_Per_Piece; L2 := L1 / N_Bits_Per_Piece + 1; X_Extra := 0.0; if (J + L2 > N_Pieces_Of_Piby2) then L2 := N_Pieces_Of_Piby2 - J; end if; for I in reverse J .. J + L2 loop X_Extra := X_Extra + Piby2_Piece (I); end loop; X_Trail := X_Trail - K * X_Extra; -- Finally, recast the answer in Common_Float. Tmp_R1 := X_Lead; R2 := ((X_Lead - F) - (Tmp_R1 - F)) + X_Trail; R1 := Tmp_R1; return; end Kp_Pi2rd; ------------------------------------------------------------------------