diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2012-12-05 11:50:26 +0100 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2012-12-05 11:50:26 +0100 |
commit | b9daa96e707ca488636eccded3255657ad0ef2bf (patch) | |
tree | c5c209c40ca9749ed464e50350da081265ed2a3f /gcc/ada/uintp.adb | |
parent | de6cad7c5c435279a851b6546d7cb6cd3001d96c (diff) | |
download | gcc-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.adb | 25 |
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 |