github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpf/t-trunc.c (about) 1 /* Test mpf_trunc, mpf_ceil, mpf_floor. 2 3 Copyright 2001, 2002 Free Software Foundation, Inc. 4 5 This file is part of the GNU MP Library test suite. 6 7 The GNU MP Library test suite is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 3 of the License, 10 or (at your option) any later version. 11 12 The GNU MP Library test suite is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 Public License for more details. 16 17 You should have received a copy of the GNU General Public License along with 18 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include "gmp.h" 23 #include "gmp-impl.h" 24 #include "tests.h" 25 26 27 void 28 check_print (mpf_srcptr src, mpf_srcptr got, mpf_srcptr want) 29 { 30 mp_trace_base = 16; 31 mpf_trace ("src ", src); 32 mpf_trace ("got ", got); 33 mpf_trace ("want", want); 34 35 printf ("got size=%d exp=%ld\n", SIZ(got), EXP(got)); 36 mpn_trace (" limbs=", PTR(got), (mp_size_t) ABSIZ(got)); 37 38 printf ("want size=%d exp=%ld\n", SIZ(want), EXP(want)); 39 mpn_trace (" limbs=", PTR(want), (mp_size_t) ABSIZ(want)); 40 } 41 42 void 43 check_one (mpf_srcptr src, mpf_srcptr trunc, mpf_srcptr ceil, mpf_srcptr floor) 44 { 45 mpf_t got; 46 47 mpf_init2 (got, mpf_get_prec (trunc)); 48 ASSERT_ALWAYS (PREC(got) == PREC(trunc)); 49 ASSERT_ALWAYS (PREC(got) == PREC(ceil)); 50 ASSERT_ALWAYS (PREC(got) == PREC(floor)); 51 52 #define CHECK_SEP(name, fun, want) \ 53 mpf_set_ui (got, 54321L); /* initial junk */ \ 54 fun (got, src); \ 55 MPF_CHECK_FORMAT (got); \ 56 if (mpf_cmp (got, want) != 0) \ 57 { \ 58 printf ("%s wrong\n", name); \ 59 check_print (src, got, want); \ 60 abort (); \ 61 } 62 63 CHECK_SEP ("mpf_trunc", mpf_trunc, trunc); 64 CHECK_SEP ("mpf_ceil", mpf_ceil, ceil); 65 CHECK_SEP ("mpf_floor", mpf_floor, floor); 66 67 #define CHECK_INPLACE(name, fun, want) \ 68 mpf_set (got, src); \ 69 fun (got, got); \ 70 MPF_CHECK_FORMAT (got); \ 71 if (mpf_cmp (got, want) != 0) \ 72 { \ 73 printf ("%s wrong\n", name); \ 74 check_print (src, got, want); \ 75 abort (); \ 76 } 77 78 CHECK_INPLACE ("mpf_trunc", mpf_trunc, trunc); 79 80 /* Can't do these unconditionally in case truncation by mpf_set strips 81 some low non-zero limbs which would have rounded the result. */ 82 if (ABSIZ(src) <= PREC(trunc)+1) 83 { 84 CHECK_INPLACE ("mpf_ceil", mpf_ceil, ceil); 85 CHECK_INPLACE ("mpf_floor", mpf_floor, floor); 86 } 87 88 mpf_clear (got); 89 } 90 91 void 92 check_all (mpf_ptr src, mpf_ptr trunc, mpf_ptr ceil, mpf_ptr floor) 93 { 94 /* some of these values are generated with direct field assignments */ 95 MPF_CHECK_FORMAT (src); 96 MPF_CHECK_FORMAT (trunc); 97 MPF_CHECK_FORMAT (ceil); 98 MPF_CHECK_FORMAT (floor); 99 100 check_one (src, trunc, ceil, floor); 101 102 mpf_neg (src, src); 103 mpf_neg (trunc, trunc); 104 mpf_neg (ceil, ceil); 105 mpf_neg (floor, floor); 106 check_one (src, trunc, floor, ceil); 107 } 108 109 void 110 check_various (void) 111 { 112 mpf_t src, trunc, ceil, floor; 113 int n, i; 114 115 mpf_init2 (src, 512L); 116 mpf_init2 (trunc, 256L); 117 mpf_init2 (ceil, 256L); 118 mpf_init2 (floor, 256L); 119 120 /* 0 */ 121 mpf_set_ui (src, 0L); 122 mpf_set_ui (trunc, 0L); 123 mpf_set_ui (ceil, 0L); 124 mpf_set_ui (floor, 0L); 125 check_all (src, trunc, ceil, floor); 126 127 /* 1 */ 128 mpf_set_ui (src, 1L); 129 mpf_set_ui (trunc, 1L); 130 mpf_set_ui (ceil, 1L); 131 mpf_set_ui (floor, 1L); 132 check_all (src, trunc, ceil, floor); 133 134 /* 2^1024 */ 135 mpf_set_ui (src, 1L); 136 mpf_mul_2exp (src, src, 1024L); 137 mpf_set (trunc, src); 138 mpf_set (ceil, src); 139 mpf_set (floor, src); 140 check_all (src, trunc, ceil, floor); 141 142 /* 1/2^1024, fraction only */ 143 mpf_set_ui (src, 1L); 144 mpf_div_2exp (src, src, 1024L); 145 mpf_set_si (trunc, 0L); 146 mpf_set_si (ceil, 1L); 147 mpf_set_si (floor, 0L); 148 check_all (src, trunc, ceil, floor); 149 150 /* 1/2 */ 151 mpf_set_ui (src, 1L); 152 mpf_div_2exp (src, src, 1L); 153 mpf_set_si (trunc, 0L); 154 mpf_set_si (ceil, 1L); 155 mpf_set_si (floor, 0L); 156 check_all (src, trunc, ceil, floor); 157 158 /* 123+1/2^64 */ 159 mpf_set_ui (src, 1L); 160 mpf_div_2exp (src, src, 64L); 161 mpf_add_ui (src, src, 123L); 162 mpf_set_si (trunc, 123L); 163 mpf_set_si (ceil, 124L); 164 mpf_set_si (floor, 123L); 165 check_all (src, trunc, ceil, floor); 166 167 /* integer of full prec+1 limbs, unchanged */ 168 n = PREC(trunc)+1; 169 ASSERT_ALWAYS (n <= PREC(src)+1); 170 EXP(src) = n; 171 SIZ(src) = n; 172 for (i = 0; i < SIZ(src); i++) 173 PTR(src)[i] = i+100; 174 mpf_set (trunc, src); 175 mpf_set (ceil, src); 176 mpf_set (floor, src); 177 check_all (src, trunc, ceil, floor); 178 179 /* full prec+1 limbs, 1 trimmed for integer */ 180 n = PREC(trunc)+1; 181 ASSERT_ALWAYS (n <= PREC(src)+1); 182 EXP(src) = n-1; 183 SIZ(src) = n; 184 for (i = 0; i < SIZ(src); i++) 185 PTR(src)[i] = i+200; 186 EXP(trunc) = n-1; 187 SIZ(trunc) = n-1; 188 for (i = 0; i < SIZ(trunc); i++) 189 PTR(trunc)[i] = i+201; 190 mpf_set (floor, trunc); 191 mpf_add_ui (ceil, trunc, 1L); 192 check_all (src, trunc, ceil, floor); 193 194 /* prec+3 limbs, 2 trimmed for size */ 195 n = PREC(trunc)+3; 196 ASSERT_ALWAYS (n <= PREC(src)+1); 197 EXP(src) = n; 198 SIZ(src) = n; 199 for (i = 0; i < SIZ(src); i++) 200 PTR(src)[i] = i+300; 201 EXP(trunc) = n; 202 SIZ(trunc) = n-2; 203 for (i = 0; i < SIZ(trunc); i++) 204 PTR(trunc)[i] = i+302; 205 mpf_set (floor, trunc); 206 mpf_set (ceil, trunc); 207 PTR(ceil)[0]++; 208 check_all (src, trunc, ceil, floor); 209 210 /* prec+4 limbs, 2 trimmed for size, 1 trimmed for integer */ 211 n = PREC(trunc)+4; 212 ASSERT_ALWAYS (n <= PREC(src)+1); 213 EXP(src) = n-1; 214 SIZ(src) = n; 215 for (i = 0; i < SIZ(src); i++) 216 PTR(src)[i] = i+400; 217 EXP(trunc) = n-1; 218 SIZ(trunc) = n-3; 219 for (i = 0; i < SIZ(trunc); i++) 220 PTR(trunc)[i] = i+403; 221 mpf_set (floor, trunc); 222 mpf_set (ceil, trunc); 223 PTR(ceil)[0]++; 224 check_all (src, trunc, ceil, floor); 225 226 /* F.F, carry out of ceil */ 227 EXP(src) = 1; 228 SIZ(src) = 2; 229 PTR(src)[0] = GMP_NUMB_MAX; 230 PTR(src)[1] = GMP_NUMB_MAX; 231 EXP(trunc) = 1; 232 SIZ(trunc) = 1; 233 PTR(trunc)[0] = GMP_NUMB_MAX; 234 mpf_set (floor, trunc); 235 EXP(ceil) = 2; 236 SIZ(ceil) = 1; 237 PTR(ceil)[0] = 1; 238 check_all (src, trunc, ceil, floor); 239 240 /* FF.F, carry out of ceil */ 241 EXP(src) = 2; 242 SIZ(src) = 3; 243 PTR(src)[0] = GMP_NUMB_MAX; 244 PTR(src)[1] = GMP_NUMB_MAX; 245 PTR(src)[2] = GMP_NUMB_MAX; 246 EXP(trunc) = 2; 247 SIZ(trunc) = 2; 248 PTR(trunc)[0] = GMP_NUMB_MAX; 249 PTR(trunc)[1] = GMP_NUMB_MAX; 250 mpf_set (floor, trunc); 251 EXP(ceil) = 3; 252 SIZ(ceil) = 1; 253 PTR(ceil)[0] = 1; 254 check_all (src, trunc, ceil, floor); 255 256 mpf_clear (src); 257 mpf_clear (trunc); 258 mpf_clear (ceil); 259 mpf_clear (floor); 260 } 261 262 int 263 main (void) 264 { 265 tests_start (); 266 267 check_various (); 268 269 tests_end (); 270 exit (0); 271 }