// File: /workspace/github_c_makefile_star2_O1/983[P]bigint/tests.c
// Function: main
int main(){
    int i, j;
    char buf[65536];
    bigint a[1], b[1], c[1], d[1], e[20];
    const char *text = "123456790123456790120987654320987654321";

    bigint_init(a);
    bigint_init(b);
    bigint_init(c);
    bigint_init(d);

    for (i = 0; i < 20; i++) bigint_init(e + i);

    bigint_from_str(a, text);
    bigint_from_str(b, "11111111111111111111");
    bigint_sqrt(c, a);
    assert(bigint_cmp(b, c) == 0);

    bigint_from_str(a, "1");
    bigint_from_word(b, 1);
    bigint_shift_left(a, a, 1 << 10);

    bigint_mul(c, a, a);
    bigint_sub(c, c, a);
    bigint_sub(c, c, a);
    bigint_add(c, c, b);

    bigint_sub(a, a, b);
    bigint_mul(d, a, a);

    assert(bigint_cmp(c, d) == 0);

    bigint_from_str_base(a, text, 10);

    i = strcmp(text, bigint_write(buf, sizeof(buf), a));
    assert(i == 0);

    bigint_from_int(a, INT_MIN);
    assert(bigint_double(a) == INT_MIN);

    /* max integer value that fits into double without loss of precision */
    /* pow(2, 53) = 9007199254740992 */
    bigint_from_str(a, "-9007199254740992");
    assert(bigint_double(a) == -9007199254740992.0);

    bigint_from_int(a, 0);
    assert(bigint_double(a) == 0.0);
    bigint_from_int(a, +1);
    assert(bigint_double(a) == +1);
    bigint_from_int(a, -1);
    assert(bigint_double(a) == -1);

    bigint_from_str(a, "");
    bigint_from_str(b, "0");
    bigint_from_str(c, "-0");
    assert(bigint_cmp(a, b) == 0);
    assert(bigint_cmp(a, c) == 0);

    for (i = 0; i < 12345; i++){
        int x = rand() % 12345;
        int y = rand() % 12345;
        int shift = rand() % 1234;
        if (rand() & 1) x = -x;
        if (rand() & 1) y = -y;

        bigint_from_int(a, x);
        bigint_from_int(b, y);
        bigint_from_int(e + 0, x + y);
        bigint_from_int(e + 1, x - y);
        bigint_from_int(e + 2, x * y);

        if (y != 0){
            bigint_from_int(e + 3, x / y);
            bigint_from_int(e + 4, x % y);
        }

        bigint_from_int(e + 5, sqrt(x > 0 ? x : -x));
        bigint_from_int(e + 6, bigint_int_gcd(x, y));

        bigint_cpy(c, a);
        bigint_shift_left(a, a, shift);
        bigint_shift_right(a, a, shift);

        assert(bigint_cmp(a, c) == 0);

        bigint_add(e + 10, a, b);
        bigint_sub(e + 11, a, b);
        bigint_mul(e + 12, a, b);
        bigint_div(e + 13, a, b);
        bigint_mod(e + 14, a, b);
        bigint_sqrt(e + 15, a);
        bigint_gcd(e + 16, a, b);

        for (j = 0; j < 7; j++){
            if (y == 0 && (j == 3 || j == 4)) continue;
            if (bigint_cmp(e + j, e + j + 10) != 0){
                printf("i %i, j %i failed for bigints %i, %i\n", i, j, x, y);
            }
            assert(bigint_cmp(e + j, e + j + 10) == 0);
        }
    }

    bigint_free(a);
    bigint_free(b);
    bigint_free(c);
    bigint_free(d);

    for (i = 0; i < 20; i++) bigint_free(e + i);

    puts("tests passed");

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10268, %rsp          # imm = 0x10268
movq %rsp, %rdi
callq 0x1a60
leaq 0x40(%rsp), %rdi
callq 0x1a60
leaq 0x20(%rsp), %rdi
callq 0x1a60
leaq 0x60(%rsp), %rdi
callq 0x1a60
xorl %ebx, %ebx
leaq (%rsp,%rbx), %rdi
addq $0x80, %rdi
callq 0x1a60
addq $0x18, %rbx
cmpq $0x1e0, %rbx            # imm = 0x1E0
jne 0x1235
leaq 0x3dd7(%rip), %rsi      # 0x5030
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x2891
leaq 0x3ded(%rip), %rsi      # 0x5058
leaq 0x40(%rsp), %r14
movq %r14, %rdi
callq 0x2891
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x3535
movq %r14, %rdi
movq %r15, %rsi
callq 0x1bbf
testl %eax, %eax
jne 0x180c
leaq 0x3e94(%rip), %rsi      # 0x5136
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x2891
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movl $0x1, %esi
callq 0x28e1
movq %rbx, %rdi
movq %rbx, %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x2e57
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
movq %rbx, %rdx
callq 0x2632
movq %r15, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x2a7d
movq %r15, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x2a7d
movq %r15, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x2a6e
movq %rbx, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x2a7d
leaq 0x60(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
movq %rbx, %rdx
callq 0x2632
movq %r15, %rdi
movq %r14, %rsi
callq 0x1bbf
testl %eax, %eax
jne 0x182b
leaq 0x3ce9(%rip), %rbx      # 0x5030
movq %rsp, %r14
movq %r14, %rdi
movq %rbx, %rsi
movl $0xa, %edx
callq 0x27c4
leaq 0x260(%rsp), %rdi
movl $0x10000, %esi          # imm = 0x10000
movq %r14, %rdx
callq 0x386e
movq %rbx, %rdi
movq %rax, %rsi
callq 0x1090
testl %eax, %eax
jne 0x184a
movq %rsp, %rbx
movq %rbx, %rdi
movl $0x80000000, %esi       # imm = 0x80000000
callq 0x289b
movq %rbx, %rdi
callq 0x4042
ucomisd 0x3c66(%rip), %xmm0     # 0x5008
jne 0x1869
jp 0x1869
leaq 0x3d1a(%rip), %rsi      # 0x50cf
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x2891
movq %rbx, %rdi
callq 0x4042
ucomisd 0x3c40(%rip), %xmm0     # 0x5010
jne 0x1888
jp 0x1888
movq %rsp, %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x289b
movq %rbx, %rdi
callq 0x4042
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x18a7
jp 0x18a7
movq %rsp, %rbx
movq %rbx, %rdi
movl $0x1, %esi
callq 0x289b
movq %rbx, %rdi
callq 0x4042
ucomisd 0x3bf3(%rip), %xmm0     # 0x5018
jne 0x18c6
jp 0x18c6
movq %rsp, %rbx
movq %rbx, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x289b
movq %rbx, %rdi
callq 0x4042
ucomisd 0x3bcf(%rip), %xmm0     # 0x5020
jne 0x18e5
jp 0x18e5
leaq 0x3d3f(%rip), %rsi      # 0x51a3
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x2891
leaq 0x3d4f(%rip), %rsi      # 0x51c5
leaq 0x40(%rsp), %r14
movq %r14, %rdi
callq 0x2891
leaq 0x3cc5(%rip), %rsi      # 0x514f
leaq 0x20(%rsp), %rdi
callq 0x2891
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1bbf
testl %eax, %eax
jne 0x1904
movq %rsp, %rdi
leaq 0x20(%rsp), %rsi
callq 0x1bbf
testl %eax, %eax
jne 0x1923
xorl %r15d, %r15d
callq 0x10f0
movslq %eax, %r12
imulq $-0x561f1071, %r12, %rax # imm = 0xA9E0EF8F
shrq $0x20, %rax
addl %r12d, %eax
movl %eax, %ecx
shrl $0x1f, %ecx
sarl $0xd, %eax
addl %ecx, %eax
imull $0x3039, %eax, %eax     # imm = 0x3039
subl %eax, %r12d
callq 0x10f0
movslq %eax, %rbp
imulq $-0x561f1071, %rbp, %rax # imm = 0xA9E0EF8F
shrq $0x20, %rax
addl %ebp, %eax
movl %eax, %ecx
shrl $0x1f, %ecx
sarl $0xd, %eax
addl %ecx, %eax
imull $0x3039, %eax, %eax     # imm = 0x3039
subl %eax, %ebp
callq 0x10f0
movl %eax, %ebx
callq 0x10f0
movl %r12d, %r14d
negl %r14d
testb $0x1, %al
cmovel %r12d, %r14d
callq 0x10f0
movl %ebp, %r13d
negl %r13d
testb $0x1, %al
cmovel %ebp, %r13d
movq %rsp, %rbp
movq %rbp, %rdi
movl %r14d, %esi
callq 0x289b
leaq 0x40(%rsp), %rdi
movl %r13d, %esi
callq 0x289b
leal (%r14,%r13), %esi
leaq 0x80(%rsp), %rdi
callq 0x289b
movl %r14d, %esi
subl %r13d, %esi
leaq 0x98(%rsp), %rdi
callq 0x289b
movl %r13d, %esi
imull %r14d, %esi
leaq 0xb0(%rsp), %rdi
callq 0x289b
testl %r13d, %r13d
je 0x15ba
movl %r14d, %eax
cltd
idivl %r13d
movl %edx, %ebp
leaq 0xc8(%rsp), %rdi
movl %eax, %esi
callq 0x289b
leaq 0xe0(%rsp), %rdi
movl %ebp, %esi
movq %rsp, %rbp
callq 0x289b
movl %r12d, %eax
negl %eax
cmovsl %r12d, %eax
cvtsi2sd %eax, %xmm0
ucomisd 0x3a59(%rip), %xmm0     # 0x5028
jb 0x15d7
sqrtsd %xmm0, %xmm0
jmp 0x15dc
callq 0x10d0
movslq %ebx, %rbx
imulq $-0x2b90cdcb, %rbx, %rax # imm = 0xD46F3235
shrq $0x20, %rax
addl %ebx, %eax
movl %eax, %ecx
shrl $0x1f, %ecx
sarl $0xa, %eax
addl %ecx, %eax
imull $0x4d2, %eax, %eax      # imm = 0x4D2
subl %eax, %ebx
cvttsd2si %xmm0, %esi
leaq 0xf8(%rsp), %rdi
callq 0x289b
movl %r14d, %edi
movl %r13d, %esi
callq 0x1a2f
leaq 0x110(%rsp), %rdi
movl %eax, %esi
callq 0x289b
leaq 0x20(%rsp), %r12
movq %r12, %rdi
movq %rbp, %rsi
callq 0x1c5e
movq %rbp, %rdi
movq %rbp, %rsi
movl %ebx, %edx
callq 0x2e57
movq %rbp, %rdi
movq %rbp, %rsi
movl %ebx, %edx
callq 0x2ea3
movq %rbp, %rdi
movq %r12, %rsi
callq 0x1bbf
testl %eax, %eax
jne 0x17ed
leaq 0x170(%rsp), %rdi
movq %rbp, %rsi
leaq 0x40(%rsp), %rbx
movq %rbx, %rdx
callq 0x2a6e
leaq 0x188(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x2a7d
leaq 0x1a0(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x2632
leaq 0x1b8(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x32f2
leaq 0x1d0(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x332f
leaq 0x1e8(%rsp), %rdi
movq %rbp, %rsi
callq 0x3535
leaq 0x200(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x336f
leaq 0x80(%rsp), %rbx
xorl %ebp, %ebp
testl %r13d, %r13d
sete %al
leal -0x3(%rbp), %ecx
cmpl $0x2, %ecx
setb %cl
testb %cl, %al
jne 0x174c
leaq 0xf0(%rbx), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x1bbf
testl %eax, %eax
je 0x1739
leaq 0x3a57(%rip), %rdi      # 0x517e
movl %r15d, %esi
movl %ebp, %edx
movl %r14d, %ecx
movl %r13d, %r8d
xorl %eax, %eax
callq 0x1050
movq %rbx, %rdi
movq %r12, %rsi
callq 0x1bbf
testl %eax, %eax
jne 0x17ce
incq %rbp
addq $0x18, %rbx
cmpq $0x7, %rbp
jne 0x16f7
incl %r15d
cmpl $0x3039, %r15d          # imm = 0x3039
jne 0x14bf
movq %rsp, %rdi
callq 0x1ae5
leaq 0x40(%rsp), %rdi
callq 0x1ae5
leaq 0x20(%rsp), %rdi
callq 0x1ae5
leaq 0x60(%rsp), %rdi
callq 0x1ae5
xorl %ebx, %ebx
leaq (%rsp,%rbx), %rdi
addq $0x80, %rdi
callq 0x1ae5
addq $0x18, %rbx
cmpq $0x1e0, %rbx            # imm = 0x1E0
jne 0x1791
leaq 0x3a12(%rip), %rdi      # 0x51c7
callq 0x1040
xorl %eax, %eax
addq $0x10268, %rsp          # imm = 0x10268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x39cf(%rip), %rdi      # 0x51a4
leaq 0x38a7(%rip), %rsi      # 0x5083
leaq 0x38a8(%rip), %rcx      # 0x508b
movl $0x6b, %edx
callq 0x1060
leaq 0x3974(%rip), %rdi      # 0x5168
leaq 0x3888(%rip), %rsi      # 0x5083
leaq 0x3889(%rip), %rcx      # 0x508b
movl $0x5c, %edx
callq 0x1060
leaq 0x385a(%rip), %rdi      # 0x506d
leaq 0x3869(%rip), %rsi      # 0x5083
leaq 0x386a(%rip), %rcx      # 0x508b
movl $0x19, %edx
callq 0x1060
leaq 0x3864(%rip), %rdi      # 0x5096
leaq 0x384a(%rip), %rsi      # 0x5083
leaq 0x384b(%rip), %rcx      # 0x508b
movl $0x27, %edx
callq 0x1060
leaq 0x385b(%rip), %rdi      # 0x50ac
leaq 0x382b(%rip), %rsi      # 0x5083
leaq 0x382c(%rip), %rcx      # 0x508b
movl $0x2c, %edx
callq 0x1060
leaq 0x3843(%rip), %rdi      # 0x50b3
leaq 0x380c(%rip), %rsi      # 0x5083
leaq 0x380d(%rip), %rcx      # 0x508b
movl $0x2f, %edx
callq 0x1060
leaq 0x3852(%rip), %rdi      # 0x50e1
leaq 0x37ed(%rip), %rsi      # 0x5083
leaq 0x37ee(%rip), %rcx      # 0x508b
movl $0x34, %edx
callq 0x1060
leaq 0x385b(%rip), %rdi      # 0x5109
leaq 0x37ce(%rip), %rsi      # 0x5083
leaq 0x37cf(%rip), %rcx      # 0x508b
movl $0x37, %edx
callq 0x1060
leaq 0x3854(%rip), %rdi      # 0x5121
leaq 0x37af(%rip), %rsi      # 0x5083
leaq 0x37b0(%rip), %rcx      # 0x508b
movl $0x39, %edx
callq 0x1060
leaq 0x384c(%rip), %rdi      # 0x5138
leaq 0x3790(%rip), %rsi      # 0x5083
leaq 0x3791(%rip), %rcx      # 0x508b
movl $0x3b, %edx
callq 0x1060
leaq 0x3847(%rip), %rdi      # 0x5152
leaq 0x3771(%rip), %rsi      # 0x5083
leaq 0x3772(%rip), %rcx      # 0x508b
movl $0x40, %edx
callq 0x1060
leaq 0x383e(%rip), %rdi      # 0x5168
leaq 0x3752(%rip), %rsi      # 0x5083
leaq 0x3753(%rip), %rcx      # 0x508b
movl $0x41, %edx
callq 0x1060
nop