version 1.1.1.1, 2000/09/09 14:12:19 |
version 1.1.1.2, 2003/08/25 16:06:07 |
|
|
/* mpfr_set_f -- set a MPFR number from a GNU MPF number |
/* mpfr_set_f -- set a MPFR number from a GNU MPF number |
|
|
Copyright (C) 1999-2000 PolKA project, Inria Lorraine and Loria |
Copyright 1999, 2000, 2001 Free Software Foundation, Inc. |
|
|
This file is part of the MPFR Library. |
This file is part of the MPFR Library. |
|
|
The MPFR Library is free software; you can redistribute it and/or modify |
The MPFR Library is free software; you can redistribute it and/or modify |
it under the terms of the GNU Library General Public License as published by |
it under the terms of the GNU Lesser General Public License as published by |
the Free Software Foundation; either version 2 of the License, or (at your |
the Free Software Foundation; either version 2.1 of the License, or (at your |
option) any later version. |
option) any later version. |
|
|
The MPFR Library is distributed in the hope that it will be useful, but |
The MPFR Library is distributed in the hope that it will be useful, but |
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
License for more details. |
License for more details. |
|
|
You should have received a copy of the GNU Library General Public License |
You should have received a copy of the GNU Lesser General Public License |
along with the MPFR Library; see the file COPYING.LIB. If not, write to |
along with the MPFR Library; see the file COPYING.LIB. If not, write to |
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
MA 02111-1307, USA. */ |
MA 02111-1307, USA. */ |
Line 24 MA 02111-1307, USA. */ |
|
Line 24 MA 02111-1307, USA. */ |
|
#include "gmp-impl.h" |
#include "gmp-impl.h" |
#include "longlong.h" |
#include "longlong.h" |
#include "mpfr.h" |
#include "mpfr.h" |
|
#include "mpfr-impl.h" |
|
|
void |
int |
#if __STDC__ |
mpfr_set_f (mpfr_ptr y, mpf_srcptr x, mp_rnd_t rnd_mode) |
mpfr_set_f(mpfr_ptr y, mpf_srcptr x, char rnd_mode) |
|
#else |
|
mpfr_set_f(y, x, rnd_mode) |
|
mpfr_ptr y; |
|
mpf_srcptr x; |
|
char rnd_mode; |
|
#endif |
|
{ |
{ |
mp_limb_t *my, *mx, *tmp; unsigned long cnt, sx, sy; |
mp_limb_t *my, *mx, *tmp; |
|
unsigned long cnt, sx, sy; |
|
int inexact; |
TMP_DECL(marker); |
TMP_DECL(marker); |
|
|
sx = ABS(SIZ(x)); sy = ABSSIZE(y); |
if (SIZ(x) * MPFR_SIGN(y) < 0) |
my = MANT(y); mx = MANT(x); |
MPFR_CHANGE_SIGN (y); |
|
|
if (sx==0) { /* x is zero */ |
MPFR_CLEAR_FLAGS (y); |
SET_ZERO(y); return; |
|
} |
|
|
|
count_leading_zeros(cnt, mx[sx - 1]); |
sx = ABS(SIZ(x)); /* number of limbs of the mantissa of x */ |
|
sy = 1 + (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB; |
|
my = MPFR_MANT(y); |
|
mx = PTR(x); |
|
|
if (SIZ(x)*SIGN(y)<0) CHANGE_SIGN(y); |
if (sx == 0) /* x is zero */ |
|
{ |
|
MPFR_SET_ZERO(y); |
|
return 0; /* 0 is exact */ |
|
} |
|
|
if (sy < sx) |
count_leading_zeros(cnt, mx[sx - 1]); |
|
|
|
if (sy <= sx) /* we may have to round even when sy = sx */ |
{ |
{ |
unsigned long xprec = sx * BITS_PER_MP_LIMB; |
unsigned long xprec = sx * BITS_PER_MP_LIMB; |
|
|
|
TMP_MARK(marker); |
tmp = (mp_limb_t*) TMP_ALLOC(xprec); |
tmp = (mp_limb_t*) TMP_ALLOC(xprec); |
if (cnt) mpn_lshift(tmp, mx, sx, cnt); |
if (cnt) |
else MPN_COPY(tmp, mx, sx); |
mpn_lshift(tmp, mx, sx, cnt); |
mpfr_round_raw(my, tmp, xprec, (SIZ(x)<0), PREC(y), rnd_mode); |
else |
|
MPN_COPY(tmp, mx, sx); |
|
mpfr_round_raw (my, tmp, xprec, (SIZ(x)<0), MPFR_PREC(y), rnd_mode, |
|
&inexact); |
|
TMP_FREE(marker); |
} |
} |
else |
else |
{ |
{ |
if (cnt) mpn_lshift(my + sy - sx, mx, sx, cnt); |
if (cnt) |
else MPN_COPY(my + sy - sx, mx, sy); |
mpn_lshift(my + sy - sx, mx, sx, cnt); |
|
else |
|
MPN_COPY(my + sy - sx, mx, sy); |
MPN_ZERO(my, sy - sx); |
MPN_ZERO(my, sy - sx); |
/* no rounding necessary, since y has a larger mantissa */ |
/* no rounding necessary, since y has a larger mantissa */ |
|
inexact = 0; |
} |
} |
|
|
EXP(y) = EXP(x) * BITS_PER_MP_LIMB - cnt; |
MPFR_EXP(y) = EXP(x) * BITS_PER_MP_LIMB - cnt; |
|
|
TMP_FREE(marker); |
return inexact; |
} |
} |