note
	description: "Summary description for {INTEGER_X_ARITHMETIC}."
	author: "Colin LeMahieu"
	date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
	revision: "$Revision: 87787 $"
	quote: "Every man should know that his conversations, his correspondence, and his personal life are private. -  Lyndon B. Johnson (1908-1973), Remarks, 3/10/67"

deferred class
	INTEGER_X_ARITHMETIC

inherit
	INTEGER_X_FACILITIES
	SPECIAL_ARITHMETIC
		rename
			add as add_special,
			sub as sub_special,
			mul as mul_special
		export
			{NONE}
				all
		end
	SPECIAL_COMPARISON
	SPECIAL_UTILITY

feature

	add (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X)
			-- Set `rop' to `op1' + `op2'.
		local
			wp: SPECIAL [NATURAL_32]
			wp_offset: INTEGER
			up: SPECIAL [NATURAL_32]
			vp: SPECIAL [NATURAL_32]
			usize: INTEGER_32
			vsize: INTEGER_32
			wsize: INTEGER_32
			abs_usize: INTEGER_32
			abs_vsize: INTEGER_32
			pointer_temp: READABLE_INTEGER_X
			int_temp: INTEGER_32
			junk2: NATURAL_32
			cy_limb: NATURAL_32
			op1: READABLE_INTEGER_X
			op2: READABLE_INTEGER_X
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			op1 := op1_a
			op2 := op2_a
			usize := op1.count
			vsize := op2.count
			abs_usize := usize.abs
			abs_vsize := vsize.abs
			if abs_usize < abs_vsize then
				pointer_temp := op1
				op1 := op2
				op2 := pointer_temp
				int_temp := usize
				usize := vsize
				vsize := int_temp
				int_temp := abs_usize
				abs_usize := abs_vsize
				abs_vsize := int_temp
			end
			wsize := abs_usize + 1
			target.resize (wsize)
			up := op1.item
			vp := op2.item
			wp := target.item
			if usize.bit_xor (vsize) < 0 then
				if abs_usize /= abs_vsize then
					sub_special (wp, 0, up, 0, abs_usize, vp, 0, abs_vsize, carry)
					junk2 := carry.item
					wsize := abs_usize
					wsize := normalize (wp, wp_offset, wsize)
					if usize < 0 then
						wsize := -wsize
					end
				elseif cmp (up, 0, vp, 0, abs_usize) < 0 then
					sub_n (wp, 0, vp, 0, up, 0, abs_usize, carry)
					junk2 := carry.item
					wsize := abs_usize
					wsize := normalize (wp, wp_offset, wsize)
					if usize >= 0 then
						wsize := -wsize
					end
				else
					sub_n (wp, 0, up, 0, vp, 0, abs_usize, carry)
					junk2 := carry.item
					wsize := abs_usize
					wsize := normalize (wp, wp_offset, wsize)
					if usize < 0 then
						wsize := -wsize
					end
				end
			else
				add_special (wp, 0, up, 0, abs_usize, vp, 0, abs_vsize, carry)
				cy_limb := carry.item
				wp [wp_offset + abs_usize] := cy_limb
				wsize := abs_usize + cy_limb.to_integer_32
				if usize < 0 then
					wsize := -wsize
				end
			end
			target.count := wsize
		end

	add_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL)
			-- Set `rop' to `op1' + `op2'.
		local
			usize: INTEGER_32
			wsize: INTEGER_32
			abs_usize: INTEGER_32
			cy: NATURAL_32
			junk2: NATURAL_32
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			usize := op1.count
			abs_usize := usize.abs
			wsize := abs_usize + 1
			target.resize (wsize)
			if abs_usize = 0 then
				target.item [0] := op2
				if op2 /= 0 then
					target.count := 1
				else
					target.count := 0
				end
			else
				if usize >= 0 then
					add_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry)
					cy := carry.item
					target.item [abs_usize] := cy
					wsize := abs_usize + cy.to_integer_32
				else
					if abs_usize = 1 and op1.item [0] < op2 then
						target.item [0] := op2 - op1.item [0]
						wsize := 1
					else
						sub_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry)
						junk2 := carry.item
						if target.item [abs_usize - 1] = 0 then
							wsize := - (abs_usize - 1)
						else
							wsize := - (abs_usize)
						end
					end
				end
				target.count := wsize
			end
		end

	aorsmul (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X; sub_a: INTEGER_32)
		local
			xsize: INTEGER_32
			ysize: INTEGER_32
			tsize: INTEGER_32
			wsize: INTEGER_32
			wsize_signed: INTEGER_32
			wp: INTEGER_32
			tp: SPECIAL [NATURAL_32]
			c: NATURAL_32
			high: NATURAL_32
			tmp_marker: SPECIAL [NATURAL_32]
			tp_offset: INTEGER_32
			current_temp: READABLE_INTEGER_X
			int_temp: INTEGER_32
			usize: INTEGER_32
			sub_l: INTEGER_32
			junk2: NATURAL_32
			op1: READABLE_INTEGER_X
			op2: READABLE_INTEGER_X
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			op1 := op1_a
			op2 := op2_a
			sub_l := sub_a
			xsize := op1.count
			ysize := op2.count
			if xsize = 0 or ysize = 0 then
			else
				if ysize.abs > xsize.abs then
					current_temp := op1
					op1 := op2
					op2 := current_temp
					int_temp := xsize
					xsize := ysize
					ysize := int_temp
				end
				sub_l := sub_l.bit_xor (ysize)
				ysize := ysize.abs
				if ysize = 1 then
					aorsmul_1 (target, op1, op2.item [0], sub_l)
				else
					sub_l := sub_l.bit_xor (xsize)
					xsize := xsize.abs
					wsize_signed := target.count
					sub_l := sub_l.bit_xor (wsize_signed)
					wsize := wsize_signed.abs
					tsize := xsize + ysize
					if wsize > tsize then
						if wsize + 1 > target.capacity then
							target.resize (wsize)
						end
					else
						if tsize + 1 > target.capacity then
							target.resize (tsize)
						end
					end
					if wsize_signed = 0 then
						mul_special (target.item, 0, op1.item, 0, xsize, op2.item, 0, ysize, carry)
						high := carry.item
						if high = 0 then
							tsize := tsize - 1
						end
						if sub_l >= 0 then
							target.count := tsize
						else
							target.count := -tsize
						end
					else
						create tmp_marker.make_filled (0, tsize)
						tp := tmp_marker
						tp_offset := 0
						mul_special (tmp_marker, 0, op1.item, 0, xsize, op2.item, 0, ysize, carry)
						high := carry.item
						if high = 0 then
							tsize := tsize - 1
						end
						if sub_l >= 0 then
							usize := wsize
							if usize < tsize then
								usize := tsize
								tp_offset := wp
								tsize := wsize
								wsize := usize
							end
							add_special (target.item, wp, op1.item, 0, usize, tp, 0, tsize, carry)
							c := carry.item
							target.item [wp + wsize] := c
							if c /= 0 then
								wsize := wsize + 1
							end
						else
							usize := wsize
							if usize < tsize or usize = tsize and cmp (target.item, wp, tmp_marker, 0, usize) < 0 then
								usize := tsize
								tp_offset := wp
								tsize := wsize
								wsize := usize
								wsize_signed := -wsize_signed
							end
							sub_special (target.item, wp, target.item, wp, usize, tp, tp_offset, tsize, carry)
							junk2 := carry.item
							wsize := usize
							from
							until
								wsize > 0 or target.item [wp + wsize - 1] /= 0
							loop
								wsize := wsize - 1
							end
						end
						if wsize_signed >= 0 then
							target.count := wsize
						else
							target.count := -wsize
						end
					end
				end
			end
		end

	aorsmul_1 (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL_32; sub_a: INTEGER_32)
		local
			xsize: INTEGER_32
			wsize: INTEGER_32
			wsize_signed: INTEGER_32
			new_wsize: INTEGER_32
			min_size: INTEGER_32
			dsize: INTEGER_32
			xp: INTEGER_32
			wp: INTEGER_32
			cy: NATURAL_32
			sub_l: INTEGER_32
			cy2: NATURAL_32
			d: INTEGER_32
			s: INTEGER_32
			n: INTEGER_32
			x: NATURAL_32
			p: INTEGER_32
			cy__: NATURAL_32
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			sub_l := sub_a
			xsize := op1.count
			if xsize = 0 or op2 = 0 then
			else
				sub_l := sub_l.bit_xor (xsize)
				xsize := xsize.abs
				wsize_signed := target.count
				if wsize_signed = 0 then
					target.resize (xsize + 1)
					wp := 0
					mul_1 (target.item, 0, op1.item, 0, xsize, op2, carry)
					cy := carry.item
					target.item [xsize] := cy
					if cy /= 0 then
						xsize := xsize + 1
					end
					if sub_l >= 0 then
						target.count := xsize
					else
						target.count := -xsize
					end
				else
					sub_l := sub_l.bit_xor (wsize_signed)
					wsize := wsize_signed.abs
					new_wsize := wsize.max (xsize)
					target.resize (new_wsize + 1)
					wp := 0
					xp := 0
					min_size := wsize.min (xsize)
					if sub_l >= 0 then
						addmul_1 (target.item, 0, op1.item, 0, min_size, op2, carry)
						cy := carry.item
						wp := wp + min_size
						xp := xp + min_size
						dsize := xsize - wsize
						if dsize /= 0 then
							if dsize > 0 then
								mul_1 (target.item, wp, op1.item, xp, min_size, op2, carry)
								cy2 := carry.item
							else
								dsize := -dsize
								cy2 := 0
							end
							add_1 (target.item, wp, target.item, wp, dsize, cy, carry)
							cy := cy2 + carry.item
						end
						target.item [wp + dsize] := cy
						if cy /= 0 then
							new_wsize := new_wsize + 1
						end
					else
						submul_1 (target.item, wp, op1.item, xp, min_size, op2, carry)
						cy := carry.item
						if wsize >= xsize then
							if wsize /= xsize then
								sub_1 (target.item, wp + xsize, op1.item, wp + xsize, wsize - xsize, cy, carry)
								cy := carry.item
								if cy /= 0 then
									target.item [wp + new_wsize] := (-cy.to_integer_32).bit_not.to_natural_32
									d := wp
									s := wp
									n := new_wsize
									from
										target.item [d] := target.item [s].bit_not
										d := d + 1
										s := s + 1
										n := n - 1
									until
										n = 0
									loop
										target.item [d] := target.item [s].bit_not
										d := d + 1
										s := s + 1
										n := n - 1
									end
									new_wsize := new_wsize + 1
									p := wp
									x := target.item [p] + 1
									target.item [p] := x
									if x < 1 then
										from
											p := p + 1
											target.item [p] := target.item [p] + 1
										until
											target.item [p] /= 0
										loop
											p := p + 1
											target.item [p] := target.item [p] + 1
										end
									end
									wsize_signed := -wsize_signed
								end
							else
								d := wp
								s := wp
								n := wsize
								from
									target.item [d] := target.item [s].bit_not
									s := s + 1
									d := d + 1
									n := n - 1
								until
									n = 0
								loop
									target.item [d] := target.item [s].bit_not
									s := s + 1
									d := d + 1
									n := n - 1
								end
								add_1 (target.item, wp, target.item, wp, wsize, 1, carry)
								cy := carry.item
								cy := cy - 1
								if cy = (0).to_natural_32.bit_not then
									cy2 := cy2 + 1
								end
								cy := cy + cy2
								mul_1 (target.item, wp + wsize, target.item, xp + wsize, xsize - wsize, op2, carry)
								cy__ := carry.item
								add_1 (target.item, wp + wsize, target.item, wp + wsize, xsize - wsize, cy, carry)
								cy := cy__ + carry.item
								target.item [wp + new_wsize] := cy
								if cy /= 0 then
									new_wsize := new_wsize + 1
								end
								if cy2 /= 0 then
									p := wp + wsize
									x := target.item [p]
									target.item [p] := x - 1
									if x < 1 then
										from
											p := p + 1
											target.item [p] := target.item [p] - 1
										until
											target.item [p] = 0
										loop
											p := p + 1
											target.item [p] := target.item [p] - 1
										end
									end
								end
								wsize_signed := -wsize_signed
							end
						end
						from
						until
							new_wsize <= 0 or target.item [(wp + new_wsize) * 4] /= 0
						loop
							new_wsize := new_wsize - 1
						end
					end
					if wsize_signed >= 0 then
						target.count := new_wsize
					else
						target.count := -new_wsize
					end
				end
			end
		end

	sub (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X)
			-- Set `rop' to `op1' - `op2'.
		local
			usize: INTEGER_32
			vsize: INTEGER_32
			wsize: INTEGER_32
			abs_usize: INTEGER_32
			abs_vsize: INTEGER_32
			pointer_temp: READABLE_INTEGER_X
			integer_temp: INTEGER_32
			junk2: NATURAL_32
			cy_limb: NATURAL_32
			op1: READABLE_INTEGER_X
			op2: READABLE_INTEGER_X
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			op1 := op1_a
			op2 := op2_a
			usize := op1.count
			vsize := -op2.count
			abs_usize := usize.abs
			abs_vsize := vsize.abs
			if abs_usize < abs_vsize then
				pointer_temp := op1
				op1 := op2
				op2 := pointer_temp
				integer_temp := usize
				usize := vsize
				vsize := integer_temp
				integer_temp := abs_usize
				abs_usize := abs_vsize
				abs_vsize := integer_temp
			end
			wsize := abs_usize + 1
			target.resize (wsize)
			if usize.bit_xor (vsize) < 0 then
				if abs_usize /= abs_vsize then
					sub_special (target.item, 0, op1.item, 0, abs_usize, op2.item, 0, abs_vsize, carry)
					junk2 := carry.item
					wsize := abs_usize
					from
					until
						wsize <= 0 or target.item [wsize - 1] /= 0
					loop
						wsize := wsize - 1
					end
					if usize < 0 then
						wsize := -wsize
					end
				elseif cmp (op1.item, 0, op2.item, 0, abs_usize) < 0 then
					sub_n (target.item, 0, op2.item, 0, op1.item, 0, abs_usize, carry)
					junk2 := carry.item
					wsize := abs_usize
					from
					until
						wsize <= 0 or target.item [wsize - 1] /= 0
					loop
						wsize := wsize - 1
					end
					if usize >= 0 then
						wsize := -wsize
					end
				else
					sub_n (target.item, 0, op1.item, 0, op2.item, 0, abs_usize, carry)
					junk2 := carry.item
					wsize := abs_usize
					from
					until
						wsize <= 0 or target.item [wsize - 1] /= 0
					loop
						wsize := wsize - 1
					end
					if usize < 0 then
						wsize := -wsize
					end
				end
			else
				add_special (target.item, 0, op1.item, 0, abs_usize, op2.item, 0, abs_vsize, carry)
				cy_limb := carry.item
				target.item [abs_usize] := cy_limb
				wsize := abs_usize + cy_limb.to_integer_32
				if usize < 0 then
					wsize := -wsize
				end
			end
			target.count := wsize
		end

	sub_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL)
			-- Set `rop' to `op1' - `op2'.
		local
			usize: INTEGER_32
			wsize: INTEGER_32
			abs_usize: INTEGER_32
			vval: NATURAL_32
			cy: NATURAL_32
			junk2: NATURAL_32
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			usize := op1.count
			abs_usize := usize.abs
			wsize := abs_usize + 1
			target.resize (wsize)
			if abs_usize = 0 then
				target.item [0] := vval
				if op2 /= 0 then
					target.count := -1
				else
					target.count := 0
				end
			else
				if usize < 0 then
					add_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry)
					cy := carry.item
					target.item [abs_usize] := cy
					wsize := - (abs_usize + cy.to_integer_32)
				else
					if abs_usize = 1 and op1.item [0] < op2 then
						target.item [0] := op2 - op1.item [0]
						wsize := -1
					else
						sub_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry)
						junk2 := carry.item
						if target.item [abs_usize - 1] = 0 then
							wsize := abs_usize - 1
						else
							wsize := abs_usize
						end
					end
				end
				target.count := wsize
			end
		end

	ui_sub (target: READABLE_INTEGER_X; op1: NATURAL_32; op2: READABLE_INTEGER_X)
			-- Set `rop' to `op1' - `op2'.
		local
			vn: INTEGER_32
			wn: INTEGER_32
			cy: NATURAL_32
			junk2: NATURAL_32
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			vn := op2.count
			if vn > 1 then
				if vn > target.capacity then
					target.resize (vn)
				end
				sub_1 (target.item, 0, op2.item, 0, vn, op1, carry)
				junk2 := carry.item
				if target.item [vn - 1] = 0 then
					wn := - (vn - 1)
				else
					wn := - vn
				end
			elseif vn = 1 then
				if op1 >= op2.item [0] then
					target.item [0] := op1 - op2.item [0]
					if target.item [0] /= 0 then
						wn := 1
					else
						wn := 0
					end
				else
					target.item [0] := op2.item [0] - op1
					wn := -1
				end
			elseif vn = 0 then
				target.item [0] := op1
				if op1 /= 0 then
					wn := 1
				else
					wn := 0
				end
			else
				vn := -vn
				target.resize (vn + 1)
				add_1 (target.item, 0, op2.item, 0, vn, op1, carry)
				cy := carry.item
				target.item [vn] := cy
				if cy /= 0 then
					wn := vn + 1
				else
					wn := vn
				end
			end
			target.count := wn
		end

	addmul (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: READABLE_INTEGER_X)
			-- Set `rop' to `rop' + `op1' times `op2'.
		do
			aorsmul (target, op1, op2, 0)
		end

	addmul_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL)
			-- Set `rop' to `rop' + `op1' times `op2'.
		do
			aorsmul_1 (target, op1, op2, 0)
		end

	submul (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: READABLE_INTEGER_X)
			-- Set `rop' to `rop' - `op1' times `op2'.
		do
			aorsmul (target, op1, op2, -1)
		end

	submul_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL)
			-- Set `rop' to `rop' - `op1' times `op2'.
		do
			aorsmul_1 (target, op1, op2, -1)
		end

	mul (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X)
			-- Set `rop' to `op1' times `op2'.
		local
			usize: INTEGER
			vsize: INTEGER
			wsize: INTEGER
			sign_product: INTEGER
			vp: SPECIAL [NATURAL_32]
			vp_offset: INTEGER
			up: SPECIAL [NATURAL_32]
			up_offset: INTEGER
			wp: SPECIAL [NATURAL_32]
			wp_offset: INTEGER
			cy_limb: NATURAL_32
			op_temp: READABLE_INTEGER_X
			size_temp: INTEGER_32
			op1: READABLE_INTEGER_X
			op2: READABLE_INTEGER_X
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			op1 := op1_a
			op2 := op2_a
			usize := op1.count
			vsize := op2.count
			sign_product := usize.bit_xor (vsize)
			usize := usize.abs
			vsize := vsize.abs
			if usize = 0 or vsize = 0 then
				target.count := 0
			else
				if vsize = 1 then
					if usize + 1 > target.capacity then
						target.resize (usize + 1)
					end
					wp := target.item
					mul_1 (target.item, 0, op1.item, 0, usize, op2.item [0], carry)
					cy_limb := carry.item
					target.item [usize] := cy_limb
					if cy_limb /= 0 then
						usize := usize + 1
					end
					if sign_product >= 0 then
						target.count := usize
					else
						target.count := -usize
					end
				else
					wsize := usize + vsize
					if wsize <= 32 and target /= op1 and target /= op2 then
						target.resize (wsize)
						wp := target.item
						if usize > vsize then
							mul_basecase (wp, 0, op1.item, 0, usize, op2.item, 0, vsize)
						else
							mul_basecase (wp, 0, op2.item, 0, vsize, op1.item, 0, usize)
						end
						wsize := wsize - (wp [wp_offset + wsize - 1] = 0).to_integer
						if sign_product >= 0 then
							target.count := wsize
						else
							target.count := -wsize
						end
					else
						if usize < vsize then
							op_temp := op1
							op1 := op2
							op2 := op_temp
							size_temp := usize
							usize := vsize
							vsize := size_temp
						end
						up := op1.item
						up_offset := 0
						vp := op2.item
						vp_offset := 0
						wp := target.item
						wp_offset := 0
						if target.capacity < wsize then
							create wp.make_filled (0, wsize)
							target.item := wp
						else
							if wp = up then
								create up.make_filled (0, usize)
								if wp = vp then
									vp := up
								end
								up.copy_data (wp, 0, 0, usize)
							elseif wp = vp then
								create vp.make_filled (0, vsize)
								vp.copy_data (wp, 0, 0, vsize)
							end
						end
						mul_special (wp, 0, up, 0, usize, vp, 0, vsize, carry)
						cy_limb := carry.item
						wsize := usize + vsize
						wsize := wsize - (cy_limb = 0).to_integer
						if sign_product < 0 then
							target.count := -wsize
						else
							target.count := wsize
						end
					end
				end
			end
		end

	mul_2exp (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; count_a: INTEGER)
		local
			usize: INTEGER
			abs_usize: INTEGER
			wsize: INTEGER
			limb_count: INTEGER
			wp: SPECIAL [NATURAL_32]
			wp_offset: INTEGER
			wlimb: NATURAL_32
			count: INTEGER
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			count := count_a
			usize := op1.count
			abs_usize := usize.abs
			if usize = 0 then
				target.count := 0
			else
				limb_count := count // limb_bits
				wsize := abs_usize + limb_count + 1
				target.resize (wsize)
				wp := target.item
				wsize := abs_usize + limb_count
				count := count \\ limb_bits
				if count /= 0 then
					lshift (wp, wp_offset + limb_count, op1.item, 0, abs_usize, count, carry)
					wlimb := carry.item
					if wlimb /= 0 then
						wp [wp_offset + wsize] := wlimb
						wsize := wsize + 1
					end
				else
					wp.copy_data (op1.item, 0, wp_offset + limb_count, abs_usize)
				end
				wp.fill_with (0, wp_offset, wp_offset + limb_count - 1)
				if usize >= 0 then
					target.count := wsize
				else
					target.count := -wsize
				end
			end
		end

	mul_si (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: INTEGER)
		local
			size: INTEGER
			sign_product: INTEGER
			sml: NATURAL_32
			cy: NATURAL_32
			pp: SPECIAL [NATURAL_32]
			pp_offset: INTEGER
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			size := op1.count
			sign_product := size
			if size = 0 or op2 = 0 then
				target.count := 0
			else
				size := size.abs
				sml := op2.abs.to_natural_32
				target.resize (size + 1)
				pp := target.item
				mul_1 (pp, pp_offset, op1.item, 0, size, sml, carry)
				cy := carry.item
				pp [pp_offset + size] := cy
				size := size + (cy /= 0).to_integer
			end
			if sign_product < 0 xor op2 < 0 then
				target.count := -size
			else
				target.count := size
			end
		end

	mul_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL_32)
		local
			size: INTEGER
			sign_product: INTEGER
			sml: NATURAL_32
			cy: NATURAL_32
			pp: SPECIAL [NATURAL_32]
			pp_offset: INTEGER
			carry: CELL [NATURAL_32]
		do
			create carry.put (0)
			size := op1.count
			sign_product := size
			if size = 0 or op2 = 0 then
				target.count := 0
			else
				size := size.abs
				sml := op2
				target.resize (size + 1)
				pp := target.item
				mul_1 (pp, pp_offset, op1.item, 0, size, sml, carry)
				cy := carry.item
				pp [pp_offset + size] := cy
				size := size + (cy /= 0).to_integer
			end
			if sign_product < 0 xor op2 < 0 then
				target.count := -size
			else
				target.count := size
			end
		end

	neg (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X)
			-- Set `rop' to -`op'.
		local
			usize: INTEGER_32
			size: INTEGER_32
		do
			usize := op.count
			if target /= op then
				size := usize.abs
				target.resize (size)
				target.item.copy_data (op.item, 0, 0, size)
			end
			target.count := -usize
		end

	abs (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X)
			-- Set `rop' to the absolute value of `op'.
		local
			size: INTEGER_32
		do
			size := op.count.abs
			if op /= target then
				target.resize (size)
				target.item.copy_data (op.item, 0, 0, size)
			end
			target.count := size
		end
end
