diff options
Diffstat (limited to 'scan-scan_literal.adb')
-rw-r--r-- | scan-scan_literal.adb | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/scan-scan_literal.adb b/scan-scan_literal.adb index 21c54fb73..6b2e7a615 100644 --- a/scan-scan_literal.adb +++ b/scan-scan_literal.adb @@ -228,6 +228,8 @@ procedure Scan_Literal is Dividend : Uint16_Array (0 .. Nbr_Digits); A_F : constant Sint16 := First_Digit (A); B_F : constant Sint16 := First_Digit (B); + + -- Digit corresponding to the first digit of B. Doff : constant Sint16 := Dividend'Last - B_F; Q : Uint16; C, N_C : Uint16; @@ -238,6 +240,9 @@ procedure Scan_Literal is end if; -- Copy and shift dividend. + -- Bit 15 of the most significant digit of A becomes bit 0 of the + -- most significant digit of DIVIDEND. Therefore we are sure + -- DIVIDEND < B (after realignment). C := 0; for K in 0 .. A_F loop N_C := Shift_Right (A.S (K), 15); @@ -249,6 +254,7 @@ procedure Scan_Literal is Dividend (0 .. Dividend'last - 2 - A_F) := (others => 0); -- Algorithm is the same as division by hand. + C := 0; for I in reverse Digit_Range loop Q := 0; for J in 0 .. 15 loop @@ -271,7 +277,13 @@ procedure Scan_Literal is Tmp (K) := Dividend (Doff + K) - V16; end loop; + -- If the last shift creates a carry, we are sure Dividend > B + if C /= 0 then + Borrow := 0; + end if; + Q := Q * 2; + -- Begin of : Dividend = Dividend * 2 C := 0; for K in 0 .. Doff - 1 loop N_C := Shift_Right (Dividend (K), 15); @@ -280,13 +292,17 @@ procedure Scan_Literal is end loop; if Borrow = 0 then + -- Dividend > B Q := Q + 1; + -- Dividend = Tmp * 2 + -- = (Dividend - B) * 2 for K in Doff .. Nbr_Digits loop N_C := Shift_Right (Tmp (K - Doff), 15); Dividend (K) := Shift_Left (Tmp (K - Doff), 1) or C; C := N_C; end loop; else + -- Dividend = Dividend * 2 for K in Doff .. Nbr_Digits loop N_C := Shift_Right (Dividend (K), 15); Dividend (K) := Shift_Left (Dividend (K), 1) or C; |