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