Long Multiplication and Division

Examples

LongMultiply[123, 456]

LongMultiply[456, 123]

Wow! The same answer!

LongDivide[56088, 123]

LongDivide[56088, 456]

LongMultiply[123456789, 987654321]

Here's a way to look at how numbers are carried.

LongMultiply[9, 123456789]

Implementation

RightJustify and RightIndent

RightJustify::usage = "RightJustify[x, w] 
gives a string of width w with the number x 
in the rightmost places.";

RightJustify[number_, width_] := 
	StringTake[
		StringJoin[
			Table[" ", {width}], 
			ToString @ number
		], 
	-width]

RightIndent::ussage = "RightIndent[x, {i}] gives the 
the number x as a string with i trailing blanks.";

RightIndent[number_, {indent_}] := 
	StringJoin[
		ToString @ number, 
		Table[" ", {indent - 1}]
	]

LongMultiply

LongMultiply::usage = "LongMultiply[x, y] 
shows the long multiplication of x by y. 
The numbers x and y must be non-negative integers.";

LongMultiply[x_, y_] := Module[
{X, Y, width},
{X, Y} = Map[IntegerDigits, {x, y}];
width = Length[Join @@ {X, Y}];
Print @ RightJustify[x, width];
Print @ RightJustify[y, width];
Print @ RightJustify[
	StringJoin @@ 
		Table["_", {1 + Max @ Map[Length, {X, Y}]}],
	width
];
Map[
	Print, 
	Map[RightJustify[#, width]&, 
		MapIndexed[
			RightIndent, 
			Map[
				RightJustify[#, width]&, 
				Reverse @ IntegerDigits[y] x 
			]
		]
	]
];
Print[StringJoin @@ Table["_", {width}]];
Print @ RightJustify[x y, width];
]

LongDivision

LongDivide::usage = "LongDivide[x, y] 
shows the long division of x by y. 
The numbers x and y must be non-negative integers.";

LongDivide[x_, y_] := Module[
{q, m, X, Y, Q, P, R, width},
q = Quotient[x, y];
m = Mod[x, y];
{X, Y, Q} = Map[IntegerDigits, {x, y, q}];
P = Reverse[y Q];
R = Rest @ Reverse @ Prepend[
	FoldList[Floor[#2 + #1 /10]&, m + First @ P, Rest @ P],
	m
];
width = 3 + Plus @@ Map[Length, {X, Y}];
Print @ RightJustify[ToString @ q, width];
Print @ StringJoin[
	Table[" ", {2 + Length @ Y}], 
	Table["_", {1 + Length @ X}]];
Print @ StringJoin[ToString @ y, " ) ", ToString @ x];
Map[
	LongDivideAux[X, Y, Q, width, #]&, 
		Transpose @ {y Q, R, Range @ Length @ R}
];
]

LongDivideAux[X_, Y_, Q_, width_, {yq_, r_, n_}] := 
Module[
{},
	Print @ RightJustify[
		RightIndent[
			RightJustify[
				ToString @ yq, 
				width
			], 
			{Length @ Q - n + 1}
		], 
		width
	];
	Print @ RightJustify[
		RightIndent[
			RightJustify[
				StringJoin @ Table["_", {1 + Length @ Y}],
				width], 
			{Length @ Q - n + 1}
		],
		width
	];	
	Print @ RightJustify[
		RightIndent[
			RightJustify[
				ToString @ r, 
				width
			], 
			{Length @ Q - n}
		], 
		width
	];
]