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