summaryrefslogtreecommitdiff
path: root/tests/tsub1sp.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tsub1sp.c')
-rw-r--r--tests/tsub1sp.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/tests/tsub1sp.c b/tests/tsub1sp.c
index 5a6be30d5..adc4e3aef 100644
--- a/tests/tsub1sp.c
+++ b/tests/tsub1sp.c
@@ -284,6 +284,91 @@ bug20171213_gen (mpfr_prec_t pmax)
}
}
+static void
+coverage (void)
+{
+ mpfr_t a, b, c, d, u;
+ int inex;
+
+ /* coverage test in mpfr_sub1sp: case d=1, limb > MPFR_LIMB_HIGHBIT, RNDF
+ and also RNDZ */
+ mpfr_init2 (a, 3 * GMP_NUMB_BITS);
+ mpfr_init2 (b, 3 * GMP_NUMB_BITS);
+ mpfr_init2 (c, 3 * GMP_NUMB_BITS);
+ mpfr_init2 (d, 3 * GMP_NUMB_BITS);
+ mpfr_init2 (u, 3 * GMP_NUMB_BITS);
+ mpfr_set_ui (b, 1, MPFR_RNDN);
+ mpfr_nextbelow (b); /* b = 1 - 2^(-p) */
+ mpfr_set_prec (c, GMP_NUMB_BITS);
+ mpfr_set_ui_2exp (c, 1, -1, MPFR_RNDN);
+ mpfr_nextbelow (c);
+ mpfr_nextbelow (c); /* c = 1/2 - 2*2^(-GMP_NUMB_BITS-1) */
+ mpfr_prec_round (c, 3 * GMP_NUMB_BITS, MPFR_RNDN);
+ mpfr_nextbelow (c); /* c = 1/2 - 2*2^(-GMP_NUMB_BITS-1) - 2^(-p-1) */
+ /* b-c = c */
+ mpfr_sub (a, b, c, MPFR_RNDF);
+ mpfr_sub (d, b, c, MPFR_RNDD);
+ mpfr_sub (u, b, c, MPFR_RNDU);
+ /* check a = d or u */
+ MPFR_ASSERTN(mpfr_equal_p (a, d) || mpfr_equal_p (a, u));
+
+ /* coverage test in mpfr_sub1sp: case d=p, RNDN, sb = 0, significand of b
+ is even but b<>2^e, (case 1e) */
+ mpfr_set_prec (a, 3 * GMP_NUMB_BITS);
+ mpfr_set_prec (b, 3 * GMP_NUMB_BITS);
+ mpfr_set_prec (c, 3 * GMP_NUMB_BITS);
+ mpfr_set_ui (b, 1, MPFR_RNDN);
+ mpfr_nextabove (b);
+ mpfr_nextabove (b);
+ mpfr_set_ui_2exp (c, 1, -3 * GMP_NUMB_BITS, MPFR_RNDN);
+ inex = mpfr_sub (a, b, c, MPFR_RNDN);
+ MPFR_ASSERTN(inex > 0);
+ MPFR_ASSERTN(mpfr_equal_p (a, b));
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+ mpfr_clear (c);
+ mpfr_clear (d);
+ mpfr_clear (u);
+}
+
+/* bug in mpfr_sub1sp1n, made generic */
+static void
+bug20180217 (mpfr_prec_t pmax)
+{
+ mpfr_t a, b, c;
+ int inex;
+ mpfr_prec_t p;
+
+ for (p = MPFR_PREC_MIN; p <= pmax; p++)
+ {
+ mpfr_init2 (a, p);
+ mpfr_init2 (b, p);
+ mpfr_init2 (c, p);
+ mpfr_set_ui (b, 1, MPFR_RNDN); /* b = 1 */
+ mpfr_set_ui_2exp (c, 1, -p-1, MPFR_RNDN); /* c = 2^(-p-1) */
+ /* a - b = 1 - 2^(-p-1) and should be rounded to 1 (case 2f of
+ mpfr_sub1sp) */
+ inex = mpfr_sub (a, b, c, MPFR_RNDN);
+ MPFR_ASSERTN(inex > 0);
+ MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
+ /* check also when a=b */
+ mpfr_set_ui (a, 1, MPFR_RNDN);
+ inex = mpfr_sub (a, a, c, MPFR_RNDN);
+ MPFR_ASSERTN(inex > 0);
+ MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
+ /* and when a=c */
+ mpfr_set_ui (b, 1, MPFR_RNDN); /* b = 1 */
+ mpfr_set_ui_2exp (a, 1, -p-1, MPFR_RNDN);
+ inex = mpfr_sub (a, b, a, MPFR_RNDN);
+ MPFR_ASSERTN(inex > 0);
+ MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
+ mpfr_clear (a);
+ mpfr_clear (b);
+ mpfr_clear (c);
+ }
+}
+
int
main (void)
{
@@ -291,6 +376,8 @@ main (void)
tests_start_mpfr ();
+ bug20180217 (1024);
+ coverage ();
compare_sub_sub1sp ();
test20170208 ();
bug20170109 ();