set_d.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:3k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. /* mpz_set_d(integer, val) -- Assign INTEGER with a double value VAL.
  2. Copyright 1995, 1996, 2000, 2001, 2002, 2003, 2006 Free Software Foundation,
  3. Inc.
  4. This file is part of the GNU MP Library.
  5. The GNU MP Library is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU Lesser General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or (at your
  8. option) any later version.
  9. The GNU MP Library is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  12. License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  15. #include "config.h"
  16. #if HAVE_FLOAT_H
  17. #include <float.h>  /* for DBL_MAX */
  18. #endif
  19. #include "gmp.h"
  20. #include "gmp-impl.h"
  21. /* We used to have a special case for d < MP_BASE_AS_DOUBLE, just casting
  22.    double -> limb.  Unfortunately gcc 3.3 on powerpc970-apple-darwin6.8.5
  23.    got this wrong.  (It assumed __fixunsdfdi returned its result in a single
  24.    64-bit register, where instead that function followed the calling
  25.    conventions and gave the result in two parts r3 and r4.)  Hence the use
  26.    of __gmp_extract_double in all cases.  */
  27. void
  28. mpz_set_d (mpz_ptr r, double d)
  29. {
  30.   int negative;
  31.   mp_limb_t tp[LIMBS_PER_DOUBLE];
  32.   mp_ptr rp;
  33.   mp_size_t rn;
  34.   DOUBLE_NAN_INF_ACTION (d,
  35.                          __gmp_invalid_operation (),
  36.                          __gmp_invalid_operation ());
  37.   negative = d < 0;
  38.   d = ABS (d);
  39.   rn = __gmp_extract_double (tp, d);
  40.   if (ALLOC(r) < rn)
  41.     _mpz_realloc (r, rn);
  42.   if (rn <= 0)
  43.     rn = 0;
  44.   rp = PTR (r);
  45.   switch (rn)
  46.     {
  47.     default:
  48.       MPN_ZERO (rp, rn - LIMBS_PER_DOUBLE);
  49.       rp += rn - LIMBS_PER_DOUBLE;
  50.       /* fall through */
  51. #if LIMBS_PER_DOUBLE == 2
  52.     case 2:
  53.       rp[1] = tp[1], rp[0] = tp[0];
  54.       break;
  55.     case 1:
  56.       rp[0] = tp[1];
  57.       break;
  58. #endif
  59. #if LIMBS_PER_DOUBLE == 3
  60.     case 3:
  61.       rp[2] = tp[2], rp[1] = tp[1], rp[0] = tp[0];
  62.       break;
  63.     case 2:
  64.       rp[1] = tp[2], rp[0] = tp[1];
  65.       break;
  66.     case 1:
  67.       rp[0] = tp[2];
  68.       break;
  69. #endif
  70. #if LIMBS_PER_DOUBLE == 4
  71.     case 4:
  72.       rp[3] = tp[3], rp[2] = tp[2], rp[1] = tp[1], rp[0] = tp[0];
  73.       break;
  74.     case 3:
  75.       rp[2] = tp[3], rp[1] = tp[2], rp[0] = tp[1];
  76.       break;
  77.     case 2:
  78.       rp[1] = tp[3], rp[0] = tp[2];
  79.       break;
  80.     case 1:
  81.       rp[0] = tp[3];
  82.       break;
  83. #endif
  84.     case 0:
  85.       break;
  86.     }
  87.   SIZ(r) = negative ? -rn : rn;
  88. }