// File: /workspace/github_cpp_makefile_star2_O2/aadityanaik[P]LongNums/src/longnums.cpp
// Function: LongNumber::operator*(LongNumber)
LongNumber LongNumber::operator*(LongNumber X) {
	LongNumber answer;

	if((*this) == 0 || X == 0) {
		return answer;
	}

	if(this->absolute() < std::numeric_limits<int>::max()){
		long int multiplier = this->absolute().toLong();
		answer = X * multiplier;
	} else if(X.absolute() < std::numeric_limits<int>::max()) {
		long int multiplier = X.absolute().toLong();
		answer = (*this) * multiplier;
	} else {
		//determine the value of the position to split the numbers
		//(*this) will be split into x1, x2 and X will be split into y1 and y2
		//z2 = x1y1, z0 = x2y2 and z1 = x1y2 + x2y1 = (x1 + x2) (y1 + y2) - z2 - z0
		//to be returned: z2 * b^2 + z1 * b + z0 where b is BASE ^ midpos

		//determining midpos
		int midpos, numZero;
		if((*this) >= X) {
			midpos = this->digits.size() / 2;
			//numZero = this->digits.size() - midpos;
			numZero = midpos;
		} else {
			midpos = X.digits.size() / 2;
			//numZero = X.digits.size() - midpos;
			numZero = midpos;
		}

		//declaring x1, x2, y1, y2 using vector constructor
		LongNumber x1, x2, y1, y2, z0, z1, z2;
		if(this->digits.size() <= numZero) {
			x1 = 0;
			x2.digits = this->digits;
		} else {
			x1.digits = std::vector<int>(this->digits.begin() + numZero, this->digits.end());
			x2.digits = std::vector<int>(this->digits.begin(), this->digits.begin() + numZero);
		}

		if(X.digits.size() <= numZero) {
			y1 = 0;
			y2.digits = X.digits;
		} else {
			y1.digits = std::vector<int>(X.digits.begin() + numZero, X.digits.end());
			y2.digits = std::vector<int>(X.digits.begin(), X.digits.begin() + numZero);
		}

		//removing trailing zeroes from x2 and y2
		while(*(x2.digits.end() - 1) == 0 && x2.digits.size() > 1) {
			x2.digits.erase(x2.digits.end() - 1);
		}

		while(*(y2.digits.end() - 1) == 0 && y2.digits.size() > 1) {
			y2.digits.erase(y2.digits.end() - 1);
		}

		//to find z2
		z2 = x1 * y1;

		//to find z0
		z0 = x2 * y2;

		//to find z1
		{
			LongNumber sumX, sumY, prodSums;
			sumX = x1 + x2;
			sumY = y1 + y2;
			prodSums = sumX * sumY;

			z1 = prodSums - z2 - z0;
		}		

		//get the answer
		//first append twice the number of zeros of numZeros to z2 and numZeros to z1
		for(int i = 1; i <= 2 * numZero; i++) {
			if(z2 != 0) {
				z2 = z2 * BASE;
			}

			if(i <= numZero && z1 != 0) {
				z1 = z1 * BASE;
			}
		}
		answer = z2 + z1 + z0;
	}

	answer.negative = negative ^ X.negative;

	return answer;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2c8, %rsp            # imm = 0x2C8
movq %rdx, %r12
movq %rsi, %r13
movq %rdi, %r15
callq 0x2720
leaq 0xd8(%rsp), %rsi
andq $0x0, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x295e
leaq 0x30(%rsp), %rsi
movq %r13, %rdi
callq 0x2caa
testb %al, %al
je 0x3273
leaq 0x30(%rsp), %rdi
callq 0x4d9a
jmp 0x3ae2
leaq 0xb8(%rsp), %rsi
andq $0x0, (%rsi)
leaq 0x50(%rsp), %rdi
callq 0x295e
leaq 0x50(%rsp), %rsi
movq %r12, %rdi
callq 0x2caa
movl %eax, %ebx
leaq 0x50(%rsp), %rdi
callq 0x4d9a
leaq 0x30(%rsp), %rdi
callq 0x4d9a
testb %bl, %bl
jne 0x3ae2
leaq 0x30(%rsp), %rdi
movq %r13, %rsi
callq 0x2a18
leaq 0xd8(%rsp), %rsi
movq $0x7fffffff, (%rsi)     # imm = 0x7FFFFFFF
leaq 0x50(%rsp), %rdi
callq 0x295e
leaq 0x30(%rsp), %rbx
leaq 0x50(%rsp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2ba2
movl %eax, %ebp
movq %r14, %rdi
callq 0x4d9a
movq %rbx, %rdi
callq 0x4d9a
testb %bpl, %bpl
je 0x334d
leaq 0x30(%rsp), %rdi
movq %r13, %rsi
callq 0x2a18
leaq 0x30(%rsp), %rbx
movq %rbx, %rdi
callq 0x29dc
movq %rax, %r14
movq %rbx, %rdi
callq 0x4d9a
leaq 0x30(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x3d56
leaq 0x30(%rsp), %rsi
movq %r15, %rdi
callq 0x4bdc
jmp 0x3aca
leaq 0x30(%rsp), %rdi
movq %r12, %rsi
callq 0x2a18
leaq 0xd8(%rsp), %rsi
movq $0x7fffffff, (%rsi)     # imm = 0x7FFFFFFF
leaq 0x50(%rsp), %rdi
callq 0x295e
leaq 0x30(%rsp), %rbx
leaq 0x50(%rsp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2ba2
movl %eax, %ebp
movq %r14, %rdi
callq 0x4d9a
movq %rbx, %rdi
callq 0x4d9a
testb %bpl, %bpl
je 0x33e6
leaq 0x30(%rsp), %rdi
movq %r12, %rsi
callq 0x2a18
leaq 0x30(%rsp), %rbx
movq %rbx, %rdi
callq 0x29dc
movq %rax, %r14
movq %rbx, %rdi
callq 0x4d9a
leaq 0x30(%rsp), %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x3d56
leaq 0x30(%rsp), %rsi
movq %r15, %rdi
callq 0x4bdc
jmp 0x3aca
movq %r13, %rdi
movq %r12, %rsi
movq %r15, 0x8(%rsp)
callq 0x2cba
testb %al, %al
movq %r12, %rax
cmovneq %r13, %rax
movq 0x8(%rax), %rbx
subq (%rax), %rbx
leaq 0x30(%rsp), %rdi
callq 0x2720
leaq 0x50(%rsp), %rdi
callq 0x2720
leaq 0xd8(%rsp), %rdi
callq 0x2720
leaq 0xb8(%rsp), %rdi
callq 0x2720
leaq 0x148(%rsp), %rdi
callq 0x2720
leaq 0x128(%rsp), %rdi
callq 0x2720
leaq 0x108(%rsp), %rdi
callq 0x2720
sarq $0x2, %rbx
shrq %rbx
movq (%r13), %rax
movq 0x8(%r13), %rdx
movq %rdx, %rcx
subq %rax, %rcx
sarq $0x2, %rcx
movq %rbx, 0xb0(%rsp)
movslq %ebx, %r14
cmpq %r14, %rcx
jbe 0x34e4
leaq (%rax,%r14,4), %rsi
leaq 0x10(%rsp), %rdi
leaq 0x70(%rsp), %rcx
callq 0x4bfe
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rbx
movq %rbx, %rsi
callq 0x5106
movq %rbx, %rdi
callq 0x4d9a
movq (%r13), %rsi
leaq (%rsi,%r14,4), %rdx
leaq 0x10(%rsp), %rdi
leaq 0x70(%rsp), %rcx
callq 0x4bfe
leaq 0x50(%rsp), %rdi
leaq 0x10(%rsp), %rbx
movq %rbx, %rsi
callq 0x5106
movq %rbx, %rdi
callq 0x4d9a
jmp 0x3504
leaq 0x10(%rsp), %rsi
andq $0x0, (%rsi)
leaq 0x30(%rsp), %rdi
callq 0x2990
leaq 0x50(%rsp), %rdi
movq %r13, %rsi
callq 0x49be
movq (%r12), %rax
movq 0x8(%r12), %rdx
movq %rdx, %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %r14, %rcx
jbe 0x3582
leaq (%rax,%r14,4), %rsi
leaq 0x10(%rsp), %rdi
leaq 0x70(%rsp), %rcx
callq 0x4bfe
leaq 0xd8(%rsp), %rdi
leaq 0x10(%rsp), %rbx
movq %rbx, %rsi
callq 0x5106
movq %rbx, %rdi
callq 0x4d9a
movq (%r12), %rsi
leaq (%rsi,%r14,4), %rdx
leaq 0x10(%rsp), %rdi
leaq 0x70(%rsp), %rcx
callq 0x4bfe
leaq 0xb8(%rsp), %rdi
leaq 0x10(%rsp), %rbx
movq %rbx, %rsi
callq 0x5106
movq %rbx, %rdi
callq 0x4d9a
jmp 0x35a8
leaq 0x10(%rsp), %rsi
andq $0x0, (%rsi)
leaq 0xd8(%rsp), %rdi
callq 0x2990
leaq 0xb8(%rsp), %rdi
movq %r12, %rsi
callq 0x49be
movq 0x58(%rsp), %rdx
cmpl $0x0, -0x4(%rdx)
jne 0x35e6
movq %rdx, %rax
subq 0x50(%rsp), %rax
cmpq $0x5, %rax
jb 0x35e6
leaq -0x4(%rdx), %rdi
leaq 0x4(%rdi), %rsi
cmpq %rdx, %rsi
je 0x35db
subq %rsi, %rdx
callq 0x2150
movq 0x58(%rsp), %rdx
addq $-0x4, %rdx
movq %rdx, 0x58(%rsp)
jmp 0x35ad
movq 0xc0(%rsp), %rdx
cmpl $0x0, -0x4(%rdx)
jne 0x3630
movq %rdx, %rax
subq 0xb8(%rsp), %rax
cmpq $0x5, %rax
jb 0x3630
leaq -0x4(%rdx), %rdi
leaq 0x4(%rdi), %rsi
cmpq %rdx, %rsi
je 0x3622
subq %rsi, %rdx
callq 0x2150
movq 0xc0(%rsp), %rdx
addq $-0x4, %rdx
movq %rdx, 0xc0(%rsp)
jmp 0x35ee
leaq 0x2a8(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x2764
leaq 0x10(%rsp), %rdi
leaq 0x30(%rsp), %rsi
leaq 0x2a8(%rsp), %rdx
callq 0x321e
leaq 0x108(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x4bdc
leaq 0x10(%rsp), %rdi
callq 0x4d9a
leaq 0x2a8(%rsp), %rdi
callq 0x4d9a
leaq 0x288(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x2764
leaq 0x10(%rsp), %rdi
leaq 0x50(%rsp), %rsi
leaq 0x288(%rsp), %rdx
callq 0x321e
leaq 0x148(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x4bdc
leaq 0x10(%rsp), %rdi
callq 0x4d9a
leaq 0x288(%rsp), %rdi
callq 0x4d9a
leaq 0x10(%rsp), %rdi
callq 0x2720
leaq 0x70(%rsp), %rdi
callq 0x2720
leaq 0x168(%rsp), %rdi
callq 0x2720
leaq 0x268(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x2764
leaq 0x90(%rsp), %rdi
leaq 0x30(%rsp), %rsi
leaq 0x268(%rsp), %rdx
callq 0x2cf4
leaq 0x10(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x4bdc
leaq 0x90(%rsp), %rdi
callq 0x4d9a
leaq 0x268(%rsp), %rdi
callq 0x4d9a
leaq 0x248(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x2764
leaq 0x90(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
leaq 0x248(%rsp), %rdx
callq 0x2cf4
leaq 0x70(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x4bdc
leaq 0x90(%rsp), %rdi
callq 0x4d9a
leaq 0x248(%rsp), %rdi
callq 0x4d9a
leaq 0x228(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x2764
leaq 0x90(%rsp), %rdi
leaq 0x10(%rsp), %rsi
leaq 0x228(%rsp), %rdx
callq 0x321e
leaq 0x168(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x4bdc
leaq 0x90(%rsp), %rdi
callq 0x4d9a
leaq 0x228(%rsp), %rdi
callq 0x4d9a
leaq 0x1e8(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0x2764
leaq 0x208(%rsp), %rdi
leaq 0x168(%rsp), %rsi
leaq 0x1e8(%rsp), %rdx
callq 0x2f36
leaq 0x1c8(%rsp), %rdi
leaq 0x148(%rsp), %rsi
callq 0x2764
leaq 0x90(%rsp), %rdi
leaq 0x208(%rsp), %rsi
leaq 0x1c8(%rsp), %rdx
callq 0x2f36
movq %r13, 0xf8(%rsp)
movq %r12, 0x100(%rsp)
leaq 0x128(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x4bdc
leaq 0x90(%rsp), %rdi
callq 0x4d9a
leaq 0x1c8(%rsp), %rdi
callq 0x4d9a
leaq 0x208(%rsp), %rdi
callq 0x4d9a
leaq 0x1e8(%rsp), %rdi
callq 0x4d9a
leaq 0x168(%rsp), %rdi
callq 0x4d9a
leaq 0x70(%rsp), %rdi
callq 0x4d9a
leaq 0x10(%rsp), %r13
movq %r13, %rdi
callq 0x4d9a
movq 0xb0(%rsp), %rax
leal (%rax,%rax), %r15d
pushq $0x1
popq %rbx
leaq 0x108(%rsp), %rbp
leaq 0x128(%rsp), %r14
cmpl %r15d, %ebx
jg 0x39d4
movq %r14, %r12
andq $0x0, 0x70(%rsp)
movq %r13, %rdi
leaq 0x70(%rsp), %rsi
callq 0x295e
movq %rbp, %rdi
movq %r13, %rsi
callq 0x2cea
movl %eax, %r14d
movq %r13, %rdi
callq 0x4d9a
testb %r14b, %r14b
je 0x396b
movslq 0x57ab(%rip), %rdx      # 0x90f8
movq %r13, %rdi
movq %rbp, %rsi
callq 0x3d56
movq %rbp, %rdi
movq %r13, %rsi
callq 0x4bdc
movq %r13, %rdi
callq 0x4d9a
cmpl 0xb0(%rsp), %ebx
jg 0x39ca
andq $0x0, 0x70(%rsp)
movq %r13, %rdi
leaq 0x70(%rsp), %rsi
callq 0x295e
movq %r12, %rdi
movq %r13, %rsi
callq 0x2cea
movl %eax, %r14d
movq %r13, %rdi
callq 0x4d9a
testb %r14b, %r14b
movq %r12, %r14
je 0x39cd
movslq 0x574c(%rip), %rdx      # 0x90f8
movq %r13, %rdi
movq %r14, %rsi
callq 0x3d56
movq %r14, %rdi
movq %r13, %rsi
callq 0x4bdc
movq %r13, %rdi
callq 0x4d9a
movq %r12, %r14
incl %ebx
jmp 0x390c
leaq 0x1a8(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x2764
leaq 0x70(%rsp), %rdi
leaq 0x108(%rsp), %rsi
leaq 0x1a8(%rsp), %rdx
movq 0x8(%rsp), %r15
callq 0x2cf4
movq 0x100(%rsp), %r12
movq 0xf8(%rsp), %r13
leaq 0x188(%rsp), %rdi
leaq 0x148(%rsp), %rsi
callq 0x2764
leaq 0x10(%rsp), %rdi
leaq 0x70(%rsp), %rsi
leaq 0x188(%rsp), %rdx
callq 0x2cf4
leaq 0x10(%rsp), %rsi
movq %r15, %rdi
callq 0x4bdc
leaq 0x10(%rsp), %rdi
callq 0x4d9a
leaq 0x188(%rsp), %rdi
callq 0x4d9a
leaq 0x70(%rsp), %rdi
callq 0x4d9a
leaq 0x1a8(%rsp), %rdi
callq 0x4d9a
leaq 0x108(%rsp), %rdi
callq 0x4d9a
leaq 0x128(%rsp), %rdi
callq 0x4d9a
leaq 0x148(%rsp), %rdi
callq 0x4d9a
leaq 0xb8(%rsp), %rdi
callq 0x4d9a
leaq 0xd8(%rsp), %rdi
callq 0x4d9a
leaq 0x50(%rsp), %rdi
callq 0x4d9a
leaq 0x30(%rsp), %rdi
callq 0x4d9a
movb 0x18(%r13), %al
cmpb 0x18(%r12), %al
setne 0x18(%r15)
movq %r15, %rax
addq $0x2c8, %rsp            # imm = 0x2C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3ceb
jmp 0x3ceb
jmp 0x3ceb
jmp 0x3ceb
jmp 0x3ceb
jmp 0x3ceb
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0x4d9a
jmp 0x3b27
movq %rax, %r14
leaq 0x188(%rsp), %rdi
callq 0x4d9a
jmp 0x3b39
movq %rax, %r14
leaq 0x70(%rsp), %rdi
callq 0x4d9a
jmp 0x3b48
movq %rax, %r14
leaq 0x1a8(%rsp), %rdi
jmp 0x3ce4
jmp 0x3ceb
movq %rax, %r14
leaq 0x90(%rsp), %rdi
callq 0x4d9a
jmp 0x3b6f
movq %rax, %r14
leaq 0x1c8(%rsp), %rdi
callq 0x4d9a
jmp 0x3b81
movq %rax, %r14
leaq 0x208(%rsp), %rdi
callq 0x4d9a
jmp 0x3b93
movq %rax, %r14
leaq 0x1e8(%rsp), %rdi
jmp 0x3bfe
jmp 0x3c05
movq %rax, %r14
leaq 0x90(%rsp), %rdi
callq 0x4d9a
jmp 0x3bb4
movq %rax, %r14
leaq 0x228(%rsp), %rdi
jmp 0x3bfe
jmp 0x3c05
movq %rax, %r14
leaq 0x90(%rsp), %rdi
callq 0x4d9a
jmp 0x3bd5
movq %rax, %r14
leaq 0x248(%rsp), %rdi
jmp 0x3bfe
jmp 0x3c05
movq %rax, %r14
leaq 0x90(%rsp), %rdi
callq 0x4d9a
jmp 0x3bf6
movq %rax, %r14
leaq 0x268(%rsp), %rdi
callq 0x4d9a
jmp 0x3c08
movq %rax, %r14
leaq 0x168(%rsp), %rdi
callq 0x4d9a
leaq 0x70(%rsp), %rdi
callq 0x4d9a
jmp 0x3cdf
movq %rax, %r14
jmp 0x3c15
jmp 0x3cdc
jmp 0x3ceb
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0x4d9a
jmp 0x3c45
movq %rax, %r14
leaq 0x288(%rsp), %rdi
jmp 0x3ce4
jmp 0x3ceb
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0x4d9a
jmp 0x3c69
movq %rax, %r14
leaq 0x2a8(%rsp), %rdi
jmp 0x3ce4
jmp 0x3ceb
jmp 0x3ceb
movq %rax, %r14
jmp 0x3cfb
movq %rax, %r14
jmp 0x3d08
movq %rax, %r14
jmp 0x3d15
movq %rax, %r14
jmp 0x3d22
jmp 0x3cb9
jmp 0x3ccd
jmp 0x3cc8
jmp 0x3cd7
jmp 0x3cd2
jmp 0x3cd7
jmp 0x3cd2
jmp 0x3cc8
jmp 0x3cc8
jmp 0x3cd2
jmp 0x3cd2
jmp 0x3cd2
jmp 0x3cc8
jmp 0x3cd2
jmp 0x3cdc
jmp 0x3ceb
movq %r15, 0x8(%rsp)
movq %rax, %r14
jmp 0x3d2f
jmp 0x3cc8
jmp 0x3cdc
jmp 0x3cdc
jmp 0x3ceb
jmp 0x3ceb
movq %r15, 0x8(%rsp)
movq %rax, %r14
jmp 0x3d39
movq %r15, 0x8(%rsp)
movq %rax, %r14
jmp 0x3d43
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0x4d9a
jmp 0x3cee
movq %rax, %r14
leaq 0x108(%rsp), %rdi
callq 0x4d9a
leaq 0x128(%rsp), %rdi
callq 0x4d9a
leaq 0x148(%rsp), %rdi
callq 0x4d9a
leaq 0xb8(%rsp), %rdi
callq 0x4d9a
leaq 0xd8(%rsp), %rdi
callq 0x4d9a
leaq 0x50(%rsp), %rdi
callq 0x4d9a
leaq 0x30(%rsp), %rdi
callq 0x4d9a
movq 0x8(%rsp), %rdi
callq 0x4d9a
movq %r14, %rdi
callq 0x2190
nop