/* Copyright (C) 2015 William Hart Copyright (C) 2015 Fredrik Johansson Copyright (C) 2015 Kushagra Singh This file is part of FLINT. FLINT is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #define ulong ulongxx /* interferes with system includes */ #include #undef ulong #include "flint.h" #include "ulong_extras.h" mp_limb_t n_cbrt_newton_iteration(mp_limb_t n) { int iter, bits; mp_limb_t ret; double val, x, xsq, dx; /* upper_limit is the max cube root possible for one word */ #ifdef FLINT64 const mp_limb_t upper_limit = 2642245; /* 2642245 < (2^64)^(1/3) */ #else const mp_limb_t upper_limit = 1625; /* 1625 < (2^32)^(1/3) */ #endif val = (double)n; bits = FLINT_BIT_COUNT(n); if (bits < 46) /* one iteration seems to be sufficient for n < 2^46 */ iter = 1; else iter = 2; /* 2 gives us a precise enough answer for any mp_limb_t */ x = n_cbrt_estimate((double)n); /* initial estimate */ /* Newton's iterations to get cube root */ val = (double)n; while(iter--) { xsq = x * x; dx = val / xsq; dx -= x; dx *= 0.333333333333333; /* dx = dx * (1/3) */ x += dx; } /* In case ret^3 or (ret+1)^3 will cause overflow */ ret = x; if (ret >= upper_limit) { if (n >= upper_limit * upper_limit * upper_limit) return upper_limit; ret = upper_limit - 1; } while (ret * ret * ret <= n) { (ret) += 1; if (ret == upper_limit) break; } while (ret * ret * ret > n) (ret) -= 1; return ret; }