1/* __gmpfr_ceil_log2 - returns ceil(log(d)/log(2)) 2 3Copyright 1999-2004, 2006-2023 Free Software Foundation, Inc. 4Contributed by the AriC and Caramba projects, INRIA. 5 6This file is part of the GNU MPFR Library. 7 8The GNU MPFR Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MPFR Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23#include "mpfr-impl.h" 24 25/* returns ceil(log(d)/log(2)) if d > 0, 26 -1023 if d = +0, 27 and floor(log(-d)/log(2))+1 if d < 0 28*/ 29long 30__gmpfr_ceil_log2 (double d) 31{ 32 long exp; 33#if _MPFR_IEEE_FLOATS 34 union mpfr_ieee_double_extract x; 35 36 x.d = d; 37 /* The cast below is useless in theory, but let us not depend on the 38 integer promotion rules (for instance, tcc is currently wrong). */ 39 exp = (long) x.s.exp - 1023; 40 MPFR_ASSERTN (exp < 1023); /* fail on infinities */ 41 x.s.exp = 1023; /* value for 1 <= d < 2 */ 42 if (x.d != 1.0) /* d: not a power of two? */ 43 exp++; 44 return exp; 45#else /* _MPFR_IEEE_FLOATS */ 46 double m; 47 48 if (d < 0.0) 49 return __gmpfr_floor_log2 (-d) + 1; 50 else if (d == 0.0) 51 return -1023; 52 else if (d >= 1.0) 53 { 54 exp = 0; 55 for (m = 1.0; m < d; m *= 2.0) 56 exp++; 57 } 58 else 59 { 60 exp = 1; 61 for (m = 1.0; m >= d; m *= 0.5) 62 exp--; 63 } 64#endif /* _MPFR_IEEE_FLOATS */ 65 return exp; 66} 67 68