top(1): Raise WARNS to 6 and fix warnings.
[dragonfly.git] / contrib / gmp / mpz / sqrt.c
blobc067e63113de2be87cf76d57ae4ed509ed8be72f
1 /* mpz_sqrt(root, u) -- Set ROOT to floor(sqrt(U)).
3 Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2005 Free Software Foundation,
4 Inc.
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
21 #include <stdio.h> /* for NULL */
22 #include "gmp.h"
23 #include "gmp-impl.h"
25 void
26 mpz_sqrt (mpz_ptr root, mpz_srcptr op)
28 mp_size_t op_size, root_size;
29 mp_ptr root_ptr, op_ptr;
30 mp_ptr free_me = NULL;
31 mp_size_t free_me_size;
32 TMP_DECL;
34 TMP_MARK;
35 op_size = op->_mp_size;
36 if (op_size <= 0)
38 if (op_size < 0)
39 SQRT_OF_NEGATIVE;
40 SIZ(root) = 0;
41 return;
44 /* The size of the root is accurate after this simple calculation. */
45 root_size = (op_size + 1) / 2;
47 root_ptr = root->_mp_d;
48 op_ptr = op->_mp_d;
50 if (root->_mp_alloc < root_size)
52 if (root_ptr == op_ptr)
54 free_me = root_ptr;
55 free_me_size = root->_mp_alloc;
57 else
58 (*__gmp_free_func) (root_ptr, root->_mp_alloc * BYTES_PER_MP_LIMB);
60 root->_mp_alloc = root_size;
61 root_ptr = (mp_ptr) (*__gmp_allocate_func) (root_size * BYTES_PER_MP_LIMB);
62 root->_mp_d = root_ptr;
64 else
66 /* Make OP not overlap with ROOT. */
67 if (root_ptr == op_ptr)
69 /* ROOT and OP are identical. Allocate temporary space for OP. */
70 op_ptr = (mp_ptr) TMP_ALLOC (op_size * BYTES_PER_MP_LIMB);
71 /* Copy to the temporary space. Hack: Avoid temporary variable
72 by using ROOT_PTR. */
73 MPN_COPY (op_ptr, root_ptr, op_size);
77 mpn_sqrtrem (root_ptr, NULL, op_ptr, op_size);
79 root->_mp_size = root_size;
81 if (free_me != NULL)
82 (*__gmp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
83 TMP_FREE;