xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tmul_d.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1 /* Test file for mpfr_mul_d
2 
3 Copyright 2007-2023 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramba projects, INRIA.
5 
6 This file is part of the GNU MPFR Library.
7 
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22 
23 #include <float.h>
24 
25 #include "mpfr-test.h"
26 
27 static void
check_nans(void)28 check_nans (void)
29 {
30   mpfr_t  x, y;
31   int inexact;
32 
33   mpfr_init2 (x, 123);
34   mpfr_init2 (y, 123);
35 
36   /* nan * 1.0 is nan */
37   mpfr_set_nan (x);
38   mpfr_clear_flags();
39   inexact = mpfr_mul_d (y, x, 1.0, MPFR_RNDN);
40   MPFR_ASSERTN (inexact == 0);
41   MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
42   MPFR_ASSERTN (mpfr_nan_p (y));
43 
44   /* +inf * 1.0 == +inf */
45   mpfr_set_inf (x, 1);
46   mpfr_clear_flags();
47   inexact = mpfr_mul_d (y, x, 1.0, MPFR_RNDN);
48   MPFR_ASSERTN (inexact == 0);
49   MPFR_ASSERTN (__gmpfr_flags == 0);
50   MPFR_ASSERTN (mpfr_inf_p (y));
51   MPFR_ASSERTN (MPFR_IS_POS (y));
52 
53   /* +inf * 0.0 is nan */
54   mpfr_clear_flags();
55   inexact = mpfr_mul_d (y, x, 0.0, MPFR_RNDN);
56   MPFR_ASSERTN (inexact == 0);
57   MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
58   MPFR_ASSERTN (mpfr_nan_p (y));
59 
60   /* -inf * 1.0 == -inf */
61   mpfr_set_inf (x, -1);
62   mpfr_clear_flags();
63   inexact = mpfr_mul_d (y, x, 1.0, MPFR_RNDN);
64   MPFR_ASSERTN (inexact == 0);
65   MPFR_ASSERTN (__gmpfr_flags == 0);
66   MPFR_ASSERTN (mpfr_inf_p (y));
67   MPFR_ASSERTN (MPFR_IS_NEG (y));
68 
69   mpfr_clear (x);
70   mpfr_clear (y);
71 }
72 
73 static void
bug20171218(void)74 bug20171218 (void)
75 {
76   mpfr_t a, b;
77   mpfr_init2 (a, 22);
78   mpfr_init2 (b, 1312);
79   mpfr_set_str (b, "1.ffffffffffffffffffc3e0007ffe000700fff8001fff800000000007e0fffe0007fffffff00001f800000003ffffffe1fc00000003fffe7c03ffffffffffffffe000000fffffffff83f0000007ffc03ffffffffc0007ff0000ffcfffffe00000f80000000003c007ffffffff3ff807ffffffffff000000000000001fc000fffe000600000ff0003ffe00fffffffc00001ffc0fffffffffff00000807fe03ffffffc01ffe", 16, MPFR_RNDN);
80   mpfr_mul_d (a, b, 0.5, MPFR_RNDF);
81   /* a should be 1 or nextbelow(1) */
82   if (mpfr_cmp_ui (a, 1) != 0)
83     {
84       mpfr_nextabove (a);
85       MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
86     }
87   mpfr_clear (a);
88   mpfr_clear (b);
89 }
90 
91 #define TEST_FUNCTION mpfr_mul_d
92 #define DOUBLE_ARG2
93 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
94 #include "tgeneric.c"
95 
96 int
main(void)97 main (void)
98 {
99   mpfr_t x, y, z;
100   double d;
101   int inexact;
102 
103   tests_start_mpfr ();
104 
105   bug20171218 ();
106 
107   /* check with enough precision */
108   mpfr_init2 (x, IEEE_DBL_MANT_DIG);
109   mpfr_init2 (y, IEEE_DBL_MANT_DIG);
110   mpfr_init2 (z, IEEE_DBL_MANT_DIG);
111 
112   mpfr_set_str (y, "4096", 10, MPFR_RNDN);
113   d = 0.125;
114   mpfr_clear_flags ();
115   inexact = mpfr_mul_d (x, y, d, MPFR_RNDN);
116   if (inexact != 0)
117     {
118       printf ("Inexact flag error in mpfr_mul_d\n");
119       exit (1);
120     }
121   mpfr_set_str (z, "512", 10, MPFR_RNDN);
122   if (mpfr_cmp (z, x))
123     {
124       printf ("Error in mpfr_mul_d (");
125       mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
126       printf (" + %.20g)\nexpected ", d);
127       mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
128       printf ("\ngot     ");
129       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
130       printf ("\n");
131       exit (1);
132     }
133   mpfr_clears (x, y, z, (mpfr_ptr) 0);
134 
135   check_nans ();
136 
137   test_generic (MPFR_PREC_MIN, 1000, 100);
138 
139   tests_end_mpfr ();
140   return 0;
141 }
142