# Infinite While loop

I have an exercise where I need to input a multi-digit number and evaluate the square of the sum of its digits. I am new to Mathematica and I can't figure out why I'm getting an infinite loop. This is my code:

n = Input["Enter a multi-digit number"];
sum = 0;
While[n > 0, sum = sum + Mod[n, 10]; n = n/10];
Print["The square of the sum of the digits is: ", sum * sum];


Any ideas what I'm doing wrong?

• Do you need to use a While loop? – NonDairyNeutrino Sep 25 '18 at 0:49
• If you keep dividing n by 10, it gets smaller, but it can't ever get below 0. Maybe try While[n>1... – bill s Sep 25 '18 at 0:52
• @ThatGravityGuy It isn't specified in the exercise, but considering that the lecture covers while and for loops, I'm guessing that it should be done using one of them. – D. D. Sep 25 '18 at 0:52
• It looks like you are assuming n is an integer and at some point when dividing by 10 it will truncate to 0. It is not so try While [ Floor[n]>0,... – jmm Sep 25 '18 at 0:58
• @bills that does fix the infinite loop, thanks! Now I've run in another problem where Mod doesn't give me the correct result. For example when I input 32 Mod[n, 10] gives me 16/5 in the first iteration, but it should be 2. – D. D. Sep 25 '18 at 1:00

The crux of the matter is how n is changed on each iteration.

## Math

Consider a multi-digit integer $$n = a_1 a_2 a_3 \ldots a_N$$, where $$a_k$$ is the $$k$$-th digit of $$n$$ in base $$10$$, and $$a_1 \neq 0$$.

Then, since $$a_1 a_2 \ldots a_N = \left( a_1 a_2 \ldots a_{N-1} \right)10 + a_N$$,

$$$$\text{ mod}(n, 10) = \text{ mod}(a_1 a_2 \ldots a_N, 10) = a_N$$$$

Therefore $$n - \mathrm{mod}(n,10) = \left( a_1 a_2 \ldots a_{N-1} \right)10 \$$ and thus

$$$$\dfrac{n - \mathrm{mod}(n,10)}{10} = \dfrac{\left( a_1 a_2 \ldots a_{N-1} \right)10}{10} = a_1 a_2 \ldots a_{N-1}$$$$

Then nest $$N-1$$ more times.

Then, since $$\mathrm{mod}(j,10) = j$$ for $$j \in \{\mathbb{Z} : 0 \leq j < 10\}$$ and $$a_1 \in \{\mathbb{Z} : 0 < a_1 < 10\}$$ by the definition of a digit in decimal expansion and our restriction, the last re-assignment of $$n$$ is just

$$$$n = \dfrac{a_1 - \mathrm{mod}(a_1,10)}{10} = \dfrac{a_1 - a_1}{10} = 0$$$$

which breaks on next test of $$n > 0$$.

So, the appropriate change of $$n$$ on each iteration is $$\boxed{n = \dfrac{n - \mathrm{mod}(n,10)}{10}}$$.

## Code

Block[
{n = Input["Enter a multi-digit number"], sum = 0},
While[n > 0, sum = sum + Mod[n, 10]; n = (n - Mod[n, 10])/10];
StringForm["The square of the sum of the digits is: ", (sum)^2]
]

Block[
{n = #, sum = 0},
While[n > 0, sum = sum + Mod[n, 10]; n = (n - Mod[n, 10])/10];
StringForm["The square of the sum of the digits is: ", (sum)^2]
] & /@ {11, 12, 21, 111}//Column


The square of the sum of the digits is: 4

The square of the sum of the digits is: 9

The square of the sum of the digits is: 9

The square of the sum of the digits is: 9

Another Method

If, in the case that you don't need to use a While loop, you can use the built in RealDigits (or IntegerDigits if n is always an integer) to get a list of the digits of any real number.

Total[First@RealDigits@Input["Enter a multi-digit number"]]^2

Total[First@RealDigits@#]^2 & /@ {11, 11., 11.1}


{4, 4, 9}

Alternatively, you can use Quotient instead of /10 to remove the "rest; of the division by 10.

n = Input["Enter a multi-digit number"];
sum = 0;
While[n > 0,
sum += Mod[n, 10];
n = Quotient[n, 10]
];
Print["The square of the sum of the digits is: ", sum^2];


Just to make it clear, the source of the error you get is in n=n/10.

Unlike, say, C, Mathematica does not do type coercion. An integer divided by an integer in Mathematica can be a non-integer rational number (as we are taught in math class, not CS). Likewise, modular division will give then a rational (not integer) remainder.

@bills that does fix the infinite loop, thanks! Now I've run in another problem where Mod doesn't give me the correct result. For example when I input 32 Mod[n, 10] gives me 16/5 in the first iteration, but it should be 2.

n = 32
Mod[32, 10]   (* 2    *)
n=32/10       (* 16/5 *)
Mod[16/5, 10] (* 16/5 *)
n=(16/5)/10   (* 8/25 *)


Floor[n] == 0 now, so the loop stops.

If you want C-like integer division, refer to Henrik's answer with Quotient.