![]() Find the greatest x such that: x * (2 * base * p + x) <= c ![]() Last = (n_digits + decimals_per_digit) / decimals_per_digit + 1UL Each "digit" correspond to some decimal digits 'p' stores the digits of the root found so far. Mpz_mul(base_squared, base_squared, base_squared) the reminder, so it multplies it by base^2. At every iteration, the algorithm "move to the left" by two "digits" 'c' is basically the remainder, initially set to the original number ![]() All the variables used by GMP need to be properly initialized before use. Fallback to 0 in case of errors.Ĭonst unsigned long number = argc > 1 ? atoi(argv) : 0 Ĭonst unsigned long n_digits = argc > 2 ? atoi(argv) : 0 digits from the command line arguments. Extract the number to be square rooted and the desired number of decimal Unsigned long max_ul(unsigned long a, unsigned long b)Ĭonst unsigned long decimals_per_digit = sizeof(unsigned long) > 4 ? 18 : 9 It also uses an adapted Newton method to find the actual "digit". Instead of calculating one decimal digit at a time, this implementation uses a larger base, the greatest multiple of 10 that fits inside an unsigned long, so that it can produce 9 or 18 decimal digits at every iteration. In the following snippet I implemented the before mentioned algorithm, using GMP (but not the square root function that the library provides). Doing significantly better requires more advanced approaches and in general may not be possible.Īs already noted, you need to change the algorithm into a digit-by-digit one (there are some examples in the Wikipedia page about the methods of computing of the square roots) and use an arbitrary precision arithmetic library to perform the calculations (for instance, GMP). The easy way to make it a lot faster (but still asymptotically just as bad) is using an arbitrary-precision math library in place of strings. Of course this is very slow, but it's simple. For example, if you have the first n digits of the square root of a number as a decimal string, you can simply try appending each digit 0 to 9, then squaring the string with long multiplication (same as you learned in grade school), and choosing the last one that doesn't overshoot. If you're willing to accept O(n) space, then some cases like the one you mentioned are fairly easy. It was not something people expected to be possible. For example, in 1995 when a formula for pi was discovered that allows computing the nth binary digit in O(1) space, this was a really big deal. without working space requirement that scales with how far out you want to go) depends on both the particular irrational number and the base you want it represented in. What you've asked about is a very hard problem, and whether it's even possible to do "one by one" (i.e. ![]() I also tried to use the native sqrt() function and casting it to string number using this method, but I faced the same issue. Printf("The square root of '%d' is '%f'", number, sqrt) īut this approach stores the result in a float variable, and I don't want to depend on the limits of the float types, as I would like to extract like 10,000 digits, for instance. initially 0, is updated with the initial value of 128 Iterate until sqrt is different of temp, that is updated on the loop ![]() store the half of the given number e.g from 256 => 128 The square root of 5 is 2,23606797749979., so this'd be the expected output: 2 I want to read digit by digit the decimals of the sqrt of 5 in C. ![]()
0 Comments
Leave a Reply. |
Details
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |