===================================================================
@@ -1165,6 +1165,7 @@
Divisor_Dig1 : Int;
Divisor_Dig2 : Int;
Q_Guess : Int;
+ R_Guess : Int;
begin
-- [ NORMALIZE ] (step D1 in the algorithm). First calculate the
@@ -1218,30 +1219,26 @@
-- Note: this version of step D3 is from the original published
-- algorithm, which is known to have a bug causing overflows.
- -- See: http://www-cs-faculty.stanford.edu/~uno/err2-2e.ps.gz.
- -- In this code we are safe since our representation of double
- -- length numbers allows an expanded range.
+ -- See: http://www-cs-faculty.stanford.edu/~uno/err2-2e.ps.gz
+ -- and http://www-cs-faculty.stanford.edu/~uno/all2-pre.ps.gz.
+ -- The code below is the fixed version of this step.
- -- We don't have a proof of this claim, but the only cases we
- -- have found that show the bug in step D3 work fine here.
-
Tmp_Int := Dividend (J) * Base + Dividend (J + 1);
-- Initial guess
- if Dividend (J) = Divisor_Dig1 then
- Q_Guess := Base - 1;
- else
- Q_Guess := Tmp_Int / Divisor_Dig1;
- end if;
+ Q_Guess := Tmp_Int / Divisor_Dig1;
+ R_Guess := Tmp_Int rem Divisor_Dig1;
-- Refine the guess
- while Divisor_Dig2 * Q_Guess >
- (Tmp_Int - Q_Guess * Divisor_Dig1) * Base +
- Dividend (J + 2)
+ while Q_Guess >= Base
+ or else Divisor_Dig2 * Q_Guess >
+ R_Guess * Base + Dividend (J + 2)
loop
Q_Guess := Q_Guess - 1;
+ R_Guess := R_Guess + Divisor_Dig1;
+ exit when R_Guess >= Base;
end loop;
-- [ MULTIPLY & SUBTRACT ] (step D4). Q_Guess * Divisor is