xref: /netbsd-src/external/lgpl3/mpfr/dist/src/fmod_ui.c (revision ec6772edaf0cdcb5f52a48f4aca5e33a8fb8ecfd)
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