1 /*
2 Copyright (C) 2014 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 "mag.h"
13
14 void
mag_add_2exp_fmpz(mag_t z,const mag_t x,const fmpz_t e)15 mag_add_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t e)
16 {
17 if (mag_is_special(x))
18 {
19 if (mag_is_zero(x))
20 {
21 MAG_MAN(z) = MAG_ONE_HALF;
22 _fmpz_add_fast(MAG_EXPREF(z), e, 1);
23 }
24 else
25 {
26 mag_inf(z);
27 }
28 }
29 else
30 {
31 slong shift;
32
33 shift = _fmpz_sub_small(MAG_EXPREF(x), e);
34
35 if (shift > 0)
36 {
37 _fmpz_set_fast(MAG_EXPREF(z), MAG_EXPREF(x));
38
39 if (shift >= MAG_BITS)
40 MAG_MAN(z) = MAG_MAN(x) + LIMB_ONE;
41 else
42 MAG_MAN(z) = MAG_MAN(x) + (LIMB_ONE << (MAG_BITS - shift));
43 }
44 else
45 {
46 shift = -shift;
47
48 _fmpz_add_fast(MAG_EXPREF(z), e, 1);
49
50 if (shift >= MAG_BITS)
51 MAG_MAN(z) = MAG_ONE_HALF + LIMB_ONE;
52 else
53 MAG_MAN(z) = MAG_ONE_HALF + (MAG_MAN(x) >> (shift + 1)) + LIMB_ONE;
54 }
55
56 MAG_ADJUST_ONE_TOO_LARGE(z);
57 }
58 }
59
60