1 /* Test file for mpfr_get_decimal64 and mpfr_set_decimal64. 2 3 Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4 Contributed by the Arenaire and Cacao 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 http://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 <stdlib.h> /* for exit */ 24 #include "mpfr-test.h" 25 26 /* #define DEBUG */ 27 28 #ifdef MPFR_WANT_DECIMAL_FLOATS 29 static void 30 print_decimal64 (_Decimal64 d) 31 { 32 union ieee_double_extract x; 33 union ieee_double_decimal64 y; 34 unsigned int Gh, i; 35 36 y.d64 = d; 37 x.d = y.d; 38 Gh = x.s.exp >> 6; 39 printf ("|%d%d%d%d%d%d", x.s.sig, Gh >> 4, (Gh >> 3) & 1, 40 (Gh >> 2) & 1, (Gh >> 1) & 1, Gh & 1); 41 printf ("%d%d%d%d%d%d", (x.s.exp >> 5) & 1, (x.s.exp >> 4) & 1, 42 (x.s.exp >> 3) & 1, (x.s.exp >> 2) & 1, (x.s.exp >> 1) & 1, 43 x.s.exp & 1); 44 for (i = 20; i > 0; i--) 45 printf ("%d", (x.s.manh >> (i - 1)) & 1); 46 for (i = 32; i > 0; i--) 47 printf ("%d", (x.s.manl >> (i - 1)) & 1); 48 printf ("|\n"); 49 } 50 51 static void 52 check_inf_nan (void) 53 { 54 mpfr_t x, y; 55 _Decimal64 d; 56 57 mpfr_init2 (x, 123); 58 mpfr_init2 (y, 123); 59 60 mpfr_set_nan (x); 61 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 62 mpfr_set_ui (x, 1, MPFR_RNDZ); 63 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 64 ASSERT_ALWAYS (mpfr_nan_p (x)); 65 66 mpfr_set_inf (x, 1); 67 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 68 mpfr_set_ui (x, 1, MPFR_RNDZ); 69 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 70 ASSERT_ALWAYS (mpfr_inf_p (x) && mpfr_sgn (x) > 0); 71 72 mpfr_set_inf (x, -1); 73 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 74 mpfr_set_ui (x, 1, MPFR_RNDZ); 75 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 76 ASSERT_ALWAYS (mpfr_inf_p (x) && mpfr_sgn (x) < 0); 77 78 mpfr_set_ui (x, 0, MPFR_RNDZ); 79 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 80 mpfr_set_ui (x, 1, MPFR_RNDZ); 81 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 82 ASSERT_ALWAYS (mpfr_cmp_ui (x, 0) == 0 && MPFR_SIGN (x) > 0); 83 84 mpfr_set_ui (x, 0, MPFR_RNDZ); 85 mpfr_neg (x, x, MPFR_RNDZ); 86 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 87 mpfr_set_ui (x, 1, MPFR_RNDZ); 88 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 89 ASSERT_ALWAYS (mpfr_cmp_ui (x, 0) == 0 && MPFR_SIGN (x) < 0); 90 91 mpfr_set_ui (x, 1, MPFR_RNDZ); 92 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 93 mpfr_set_ui (x, 0, MPFR_RNDZ); 94 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 95 ASSERT_ALWAYS (mpfr_cmp_ui (x, 1) == 0); 96 97 mpfr_set_si (x, -1, MPFR_RNDZ); 98 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 99 mpfr_set_ui (x, 0, MPFR_RNDZ); 100 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 101 ASSERT_ALWAYS (mpfr_cmp_si (x, -1) == 0); 102 103 mpfr_set_ui (x, 2, MPFR_RNDZ); 104 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 105 mpfr_set_ui (x, 0, MPFR_RNDZ); 106 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 107 ASSERT_ALWAYS (mpfr_cmp_ui (x, 2) == 0); 108 109 mpfr_set_ui (x, 99, MPFR_RNDZ); 110 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 111 mpfr_set_ui (x, 0, MPFR_RNDZ); 112 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 113 ASSERT_ALWAYS (mpfr_cmp_ui (x, 99) == 0); 114 115 mpfr_set_str (x, "9999999999999999", 10, MPFR_RNDZ); 116 mpfr_set (y, x, MPFR_RNDZ); 117 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 118 mpfr_set_ui (x, 0, MPFR_RNDZ); 119 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 120 ASSERT_ALWAYS (mpfr_cmp (x, y) == 0); 121 122 /* smallest normal number */ 123 mpfr_set_str (x, "1E-383", 10, MPFR_RNDU); 124 mpfr_set (y, x, MPFR_RNDZ); 125 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 126 mpfr_set_ui (x, 0, MPFR_RNDZ); 127 mpfr_set_decimal64 (x, d, MPFR_RNDU); 128 ASSERT_ALWAYS (mpfr_cmp (x, y) == 0); 129 130 /* smallest subnormal number */ 131 mpfr_set_str (x, "1E-398", 10, MPFR_RNDU); 132 mpfr_set (y, x, MPFR_RNDZ); 133 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 134 mpfr_set_ui (x, 0, MPFR_RNDZ); 135 mpfr_set_decimal64 (x, d, MPFR_RNDU); 136 ASSERT_ALWAYS (mpfr_cmp (x, y) == 0); 137 138 /* subnormal number with exponent change when we round back 139 from 16 digits to 1 digit */ 140 mpfr_set_str (x, "9.9E-398", 10, MPFR_RNDN); 141 d = mpfr_get_decimal64 (x, MPFR_RNDU); /* should be 1E-397 */ 142 mpfr_set_ui (x, 0, MPFR_RNDZ); 143 mpfr_set_decimal64 (x, d, MPFR_RNDD); 144 mpfr_set_str (y, "1E-397", 10, MPFR_RNDN); 145 ASSERT_ALWAYS (mpfr_cmp (x, y) == 0); 146 147 /* largest number */ 148 mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ); 149 mpfr_set (y, x, MPFR_RNDZ); 150 d = mpfr_get_decimal64 (x, MPFR_RNDU); 151 mpfr_set_ui (x, 0, MPFR_RNDZ); 152 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 153 ASSERT_ALWAYS (mpfr_cmp (x, y) == 0); 154 155 mpfr_set_prec (x, 53); 156 mpfr_set_prec (y, 53); 157 158 /* largest number */ 159 mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ); 160 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 161 mpfr_set_decimal64 (y, d, MPFR_RNDU); 162 ASSERT_ALWAYS (mpfr_cmp (x, y) == 0); 163 164 mpfr_clear (x); 165 mpfr_clear (y); 166 } 167 168 static void 169 check_random (void) 170 { 171 mpfr_t x, y; 172 _Decimal64 d; 173 int i; 174 175 mpfr_init2 (x, 49); 176 mpfr_init2 (y, 49); 177 178 for (i = 0; i < 100000; i++) 179 { 180 mpfr_urandomb (x, RANDS); /* 0 <= x < 1 */ 181 /* the normal decimal64 range contains [2^(-1272), 2^1278] */ 182 mpfr_mul_2si (x, x, (i % 2550) - 1272, MPFR_RNDN); 183 if (mpfr_get_exp (x) <= -1272) 184 mpfr_mul_2exp (x, x, -1271 - mpfr_get_exp (x), MPFR_RNDN); 185 d = mpfr_get_decimal64 (x, MPFR_RNDN); 186 mpfr_set_decimal64 (y, d, MPFR_RNDN); 187 if (mpfr_cmp (x, y) != 0) 188 { 189 printf ("x="); mpfr_dump (x); 190 printf ("d="); print_decimal64 (d); 191 printf ("y="); mpfr_dump (y); 192 exit (1); 193 } 194 } 195 196 mpfr_clear (x); 197 mpfr_clear (y); 198 } 199 200 /* check with native decimal formats */ 201 static void 202 check_native (void) 203 { 204 mpfr_t x; 205 _Decimal64 d; 206 207 mpfr_init2 (x, 53); 208 209 /* check important constants are correctly converted */ 210 mpfr_set_ui (x, 17, MPFR_RNDN); 211 d = mpfr_get_decimal64 (x, MPFR_RNDN); 212 MPFR_ASSERTN(d == 17.0dd); 213 214 mpfr_set_ui (x, 42, MPFR_RNDN); 215 d = mpfr_get_decimal64 (x, MPFR_RNDN); 216 MPFR_ASSERTN(d == 42.0dd); 217 218 mpfr_set_decimal64 (x, 17.0dd, MPFR_RNDN); 219 MPFR_ASSERTN(mpfr_cmp_ui (x, 17) == 0); 220 221 mpfr_set_decimal64 (x, 42.0dd, MPFR_RNDN); 222 MPFR_ASSERTN(mpfr_cmp_ui (x, 42) == 0); 223 224 mpfr_clear (x); 225 } 226 #endif /* MPFR_WANT_DECIMAL_FLOATS */ 227 228 int 229 main (void) 230 { 231 tests_start_mpfr (); 232 mpfr_test_init (); 233 234 #ifdef MPFR_WANT_DECIMAL_FLOATS 235 #ifdef DEBUG 236 #ifdef DPD_FORMAT 237 printf ("Using DPD format\n"); 238 #else 239 printf ("Using BID format\n"); 240 #endif 241 #endif 242 check_inf_nan (); 243 check_random (); 244 check_native (); 245 #endif 246 247 tests_end_mpfr (); 248 return 0; 249 } 250