## Approximate Squaring

### June 8, 2021

Lagarias and Sloane study the “approximate squaring” map f(x) = xx⌉ and its behavior when iterated in this paper.

Consider the fraction x = n / d when n > d > 1; let’s take 8/7 as an example. In the first step, the smallest integer greater than 8/7 (the “ceiling”) is 2, and 8/7 × 2 = 16/7. In the second step, the ceiling of 16/7 is 3, so we have 16/7 × 3 = 48/7. And in the third step, the ceiling of 48/7 is 7, so we have 48/7 × 7 = 48. Now the denominator is 1 and the result is an integer, so iteration stops, and we say that 8/7 goes to 48 in 3 steps.

Study shows the iteration is chaotic; sometimes the iteration stops in just a few steps, as in 8/7, sometimes it takes longer (6/5 goes to a number with 57735 digits in 18 steps), and sometimes it’s just ridiculous (200/199 goes to a number with 10435 digits). It is conjectured but not proven that iterated approximate squaring always terminates in an integer.

Your task is to write a program that iterates approximate squaring. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

### 6 Responses to “Approximate Squaring”

1. Zack said

Nifty little drill. I suppose some people have way too much time on their hands, writing papers like this!

Here is my take on this using Julia: https://pastebin.com/TtiyB0Wu

2. Globules said

```import Data.Ratio (denominator, numerator)
import System.Environment (getArgs)

approxSq :: Rational -> Rational
approxSq x = x * toRational (ceiling x :: Integer)

iterApproxSq :: Rational -> Integer
iterApproxSq = numerator . head . iterateUntil isInteger approxSq
where isInteger = (== 1) . denominator
iterateUntil p f = dropWhile (not . p) . drop 1 . iterate f

main :: IO ()
main = do
rs <- getArgs
mapM_ (print . iterApproxSq . read) rs
```
```\$ ./approxsq 8%7 3%2 5%2 7%2 9%2 11%2 13%2 15%2 17%2 19%2 3%3 4%3 5%3
48
3
60
14
268065
33
2093
60
1204154941925628
95
1
8
1484710602474311520
```
3. Jared said

Lisp:
(defun approximate-square (number)
(loop
for n = number then (* n (ceiling n))
when (integerp n)
do (return n)))

``````> (mapcar #'approximate-square '(8/7 3/2 5/2 7/2 9/2 11/2 13/2 15/2 17/2 19/2 3/3 4/3 5/3))
(48 3 60 14 268065 33 2093 60 1204154941925628 95 1 8 1484710602474311520)
``````
4. Daniel said

Here’s a solution in Python.

```def approx_squaring(n, d):
while n % d:
n *= (n + d - 1) // d
return n // d

print(approx_squaring(8, 7))
print(approx_squaring(10, 6))
print(approx_squaring(6, 5))
```

Output:

```48
1484710602474311520
9532960047385704656...9010186950239453184
```
5. Daniel said

Here’s a solution in C using GMP.

```// \$ gcc -o approx_squaring approx_squaring.c -lgmp

#include <stdlib.h>

#include <gmp.h>

int main(int argc, char* argv[]) {
if (argc != 3) return EXIT_FAILURE;
mpz_t n;
mpz_init(n);
mpz_set_str(n, argv[1], 10);
mpz_t d;
mpz_init(d);
mpz_set_str(d, argv[2], 10);
mpz_t q;
mpz_init(q);
while (!mpz_divisible_p(n, d)) {
mpz_cdiv_q(q, n, d);
mpz_mul(n, n, q);
}
mpz_divexact(n, n, d);
gmp_printf("%Zd\n", n);
mpz_clear(n);
mpz_clear(d);
mpz_clear(q);
return EXIT_SUCCESS;
}
```

Example usage:

```\$ ./approx_squaring 8 7
48
\$ ./approx_squaring 10 6
1484710602474311520
\$ ./approx_squaring 6 5
9532960047385704656...9010186950239453184
```
6. […] is to write a program that iterates approximate squaring. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments […]