1 /*
2     Copyright (C) 2012 Fredrik Johansson
3 
4     This file is part of Arb.
5 
6     Arb is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 2.1 of the License, or
9     (at your option) any later version.  See <http://www.gnu.org/licenses/>.
10 */
11 
12 #include "fmpr.h"
13 
14 slong
_fmpr_normalise_naive(fmpz_t man,fmpz_t exp,slong prec,fmpr_rnd_t rnd)15 _fmpr_normalise_naive(fmpz_t man, fmpz_t exp, slong prec, fmpr_rnd_t rnd)
16 {
17     /* TODO: this should perhaps raise an exception to avoid ambiguity */
18     if (fmpz_is_zero(man))
19     {
20         fmpz_zero(exp);
21         return FMPR_RESULT_EXACT;
22     }
23     else
24     {
25         slong bc, val;
26 
27         bc = fmpz_bits(man);
28         val = fmpz_val2(man);
29 
30         if (bc - val <= prec)
31         {
32             if (val != 0)
33             {
34                 fmpz_tdiv_q_2exp(man, man, val);
35                 fmpz_add_ui(exp, exp, val);
36             }
37 
38             return FMPR_RESULT_EXACT;
39         }
40         else
41         {
42             slong exp_shift = bc - prec;
43 
44             if (rnd == FMPR_RND_NEAR)
45             {
46                 flint_abort();
47             }
48             else if (rnd == FMPR_RND_DOWN)
49             {
50                 fmpz_tdiv_q_2exp(man, man, exp_shift);
51             }
52             else if (rnd == FMPR_RND_FLOOR)
53             {
54                 fmpz_fdiv_q_2exp(man, man, exp_shift);
55             }
56             else if (rnd == FMPR_RND_CEIL)
57             {
58                 fmpz_cdiv_q_2exp(man, man, exp_shift);
59             }
60             else
61             {
62                 if (fmpz_sgn(man) > 0)
63                     fmpz_cdiv_q_2exp(man, man, exp_shift);
64                 else
65                     fmpz_fdiv_q_2exp(man, man, exp_shift);
66             }
67 
68             val = fmpz_val2(man);
69             exp_shift += val;
70 
71             if (val != 0)
72                 fmpz_tdiv_q_2exp(man, man, val);
73 
74             fmpz_add_ui(exp, exp, exp_shift);
75             return val - (val == prec);
76         }
77     }
78 }
79