aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/uintp.adb
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2012-12-05 11:50:26 +0100
committerArnaud Charlet <charlet@gcc.gnu.org>2012-12-05 11:50:26 +0100
commitb9daa96e707ca488636eccded3255657ad0ef2bf (patch)
treec5c209c40ca9749ed464e50350da081265ed2a3f /gcc/ada/uintp.adb
parentde6cad7c5c435279a851b6546d7cb6cd3001d96c (diff)
downloadgcc-b9daa96e707ca488636eccded3255657ad0ef2bf.zip
gcc-b9daa96e707ca488636eccded3255657ad0ef2bf.tar.gz
gcc-b9daa96e707ca488636eccded3255657ad0ef2bf.tar.bz2
[multiple changes]
2012-12-05 Robert Dewar <dewar@adacore.com> * gnatchop.adb, sem_attr.ads, sem_ch4.adb, sem_ch6.adb, exp_disp.adb, atree.adb, sem_eval.adb: Minor reformatting. 2012-12-05 Yannick Moy <moy@adacore.com> * uintp.adb (UI_Div_Rem): Correct algorithm D to remove potential overflow. 2012-12-05 Robert Dewar <dewar@adacore.com> * exp_ch4.adb (Expand_N_Op_Mod): Minor comment additions. (Expand_N_Op_Rem): Ditto. 2012-12-05 Robert Dewar <dewar@adacore.com> * sem_attr.adb: Minor reformatting. 2012-12-05 Robert Dewar <dewar@adacore.com> * usage.adb: Update lines for -gnato? switch. From-SVN: r194202
Diffstat (limited to 'gcc/ada/uintp.adb')
-rw-r--r--gcc/ada/uintp.adb25
1 files changed, 11 insertions, 14 deletions
diff --git a/gcc/ada/uintp.adb b/gcc/ada/uintp.adb
index 0761f2d..bc01466 100644
--- a/gcc/ada/uintp.adb
+++ b/gcc/ada/uintp.adb
@@ -1165,6 +1165,7 @@ package body Uintp is
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 @@ package body Uintp is
-- 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.
-
- -- 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.
+ -- 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.
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