1ba125506Smrg /* mpfr_fmod_ui -- modulo a machine integer
2ba125506Smrg
3ba125506Smrg Copyright 2000-2004, 2006-2023 Free Software Foundation, Inc.
4ba125506Smrg Contributed by the AriC and Caramba projects, INRIA.
5ba125506Smrg
6ba125506Smrg This file is part of the GNU MPFR Library.
7ba125506Smrg
8ba125506Smrg The GNU MPFR Library is free software; you can redistribute it and/or modify
9ba125506Smrg it under the terms of the GNU Lesser General Public License as published by
10ba125506Smrg the Free Software Foundation; either version 3 of the License, or (at your
11ba125506Smrg option) any later version.
12ba125506Smrg
13ba125506Smrg The GNU MPFR Library is distributed in the hope that it will be useful, but
14ba125506Smrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15ba125506Smrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16ba125506Smrg License for more details.
17ba125506Smrg
18ba125506Smrg You should have received a copy of the GNU Lesser General Public License
19ba125506Smrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20ba125506Smrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21ba125506Smrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22ba125506Smrg
23ba125506Smrg #define MPFR_NEED_LONGLONG_H
24ba125506Smrg #include "mpfr-impl.h"
25ba125506Smrg
26ba125506Smrg int
mpfr_fmod_ui(mpfr_ptr r,mpfr_srcptr x,unsigned long u,mpfr_rnd_t rnd_mode)27ba125506Smrg mpfr_fmod_ui (mpfr_ptr r, mpfr_srcptr x, unsigned long u, mpfr_rnd_t rnd_mode)
28ba125506Smrg {
29ba125506Smrg int inex;
30ba125506Smrg
31ba125506Smrg MPFR_LOG_FUNC
32*ec6772edSmrg (("x[%Pd]=%.*Rg u=%lu rnd=%d",
33ba125506Smrg mpfr_get_prec(x), mpfr_log_prec, x, u, rnd_mode),
34*ec6772edSmrg ("y[%Pd]=%.*Rg inexact=%d",
35ba125506Smrg mpfr_get_prec(r), mpfr_log_prec, r, inex));
36ba125506Smrg
37ba125506Smrg if (MPFR_UNLIKELY (u != 0))
38ba125506Smrg {
39ba125506Smrg mpfr_t uu;
40ba125506Smrg #ifdef MPFR_LONG_WITHIN_LIMB
41ba125506Smrg mp_limb_t up[1];
42ba125506Smrg int cnt;
43ba125506Smrg MPFR_SAVE_EXPO_DECL (expo);
44ba125506Smrg
45ba125506Smrg MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS);
46ba125506Smrg MPFR_ASSERTN (u == (mp_limb_t) u);
47ba125506Smrg count_leading_zeros (cnt, (mp_limb_t) u);
48ba125506Smrg *up = (mp_limb_t) u << cnt;
49ba125506Smrg
50ba125506Smrg MPFR_SAVE_EXPO_MARK (expo);
51ba125506Smrg MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
52ba125506Smrg inex = mpfr_fmod (r, x, uu, rnd_mode);
53ba125506Smrg #else
54ba125506Smrg MPFR_SAVE_EXPO_DECL (expo);
55ba125506Smrg
56ba125506Smrg mpfr_init2 (uu, sizeof (unsigned long) * CHAR_BIT);
57ba125506Smrg /* Warning: u might be outside the current exponent range! */
58ba125506Smrg MPFR_SAVE_EXPO_MARK (expo);
59ba125506Smrg mpfr_set_ui (uu, u, MPFR_RNDZ);
60ba125506Smrg inex = mpfr_fmod (r, x, uu, rnd_mode);
61ba125506Smrg mpfr_clear (uu);
62ba125506Smrg #endif /* MPFR_LONG_WITHIN_LIMB */
63ba125506Smrg MPFR_SAVE_EXPO_FREE (expo);
64ba125506Smrg inex = mpfr_check_range (r, inex, rnd_mode);
65ba125506Smrg return inex;
66ba125506Smrg }
67ba125506Smrg else
68ba125506Smrg {
69ba125506Smrg MPFR_SET_NAN (r);
70ba125506Smrg MPFR_RET_NAN;
71ba125506Smrg }
72ba125506Smrg }
73