// File: /workspace/github_c_makefile_star2_O3/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 0x1a44
leaq 0x40(%rsp), %rdi
callq 0x1a44
leaq 0x20(%rsp), %rdi
callq 0x1a44
leaq 0x60(%rsp), %rdi
callq 0x1a44
xorl %ebx, %ebx
leaq (%rsp,%rbx), %rdi
addq $0x80, %rdi
callq 0x1a44
addq $0x18, %rbx
cmpq $0x1e0, %rbx            # imm = 0x1E0
jne 0x1225
leaq 0x3ddf(%rip), %rsi      # 0x5028
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x28a6
leaq 0x3df5(%rip), %rsi      # 0x5050
leaq 0x40(%rsp), %r14
movq %r14, %rdi
callq 0x28a6
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x352b
movq %r14, %rdi
movq %r15, %rsi
callq 0x1ba3
testl %eax, %eax
jne 0x17ef
leaq 0x3e9c(%rip), %rsi      # 0x512e
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x28a6
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movl $0x1, %esi
callq 0x28f6
movq %rbx, %rdi
movq %rbx, %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x2e85
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
movq %rbx, %rdx
callq 0x2647
movq %r15, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x2a92
movq %r15, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x2a92
movq %r15, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x2a83
movq %rbx, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x2a92
leaq 0x60(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
movq %rbx, %rdx
callq 0x2647
movq %r15, %rdi
movq %r14, %rsi
callq 0x1ba3
testl %eax, %eax
jne 0x180e
leaq 0x3cf1(%rip), %rbx      # 0x5028
movq %rsp, %r14
movq %r14, %rdi
movq %rbx, %rsi
movl $0xa, %edx
callq 0x27d9
leaq 0x260(%rsp), %rdi
movl $0x10000, %esi          # imm = 0x10000
movq %r14, %rdx
callq 0x3841
movq %rbx, %rdi
movq %rax, %rsi
callq 0x1090
testl %eax, %eax
jne 0x182d
movq %rsp, %rbx
movq %rbx, %rdi
movl $0x80000000, %esi       # imm = 0x80000000
callq 0x28b0
movq %rbx, %rdi
callq 0x4004
ucomisd 0x3c76(%rip), %xmm0     # 0x5008
jne 0x184c
jp 0x184c
leaq 0x3d22(%rip), %rsi      # 0x50c7
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x28a6
movq %rbx, %rdi
callq 0x4004
ucomisd 0x3c50(%rip), %xmm0     # 0x5010
jne 0x186b
jp 0x186b
movq %rsp, %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x28b0
movq %rbx, %rdi
callq 0x4004
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x188a
jp 0x188a
movq %rsp, %rbx
movq %rbx, %rdi
movl $0x1, %esi
callq 0x28b0
movq %rbx, %rdi
callq 0x4004
ucomisd 0x3c03(%rip), %xmm0     # 0x5018
jne 0x18a9
jp 0x18a9
movq %rsp, %rbx
movq %rbx, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x28b0
movq %rbx, %rdi
callq 0x4004
ucomisd 0x3bdf(%rip), %xmm0     # 0x5020
jne 0x18c8
jp 0x18c8
leaq 0x3d47(%rip), %rsi      # 0x519b
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x28a6
leaq 0x3d57(%rip), %rsi      # 0x51bd
leaq 0x40(%rsp), %r14
movq %r14, %rdi
callq 0x28a6
leaq 0x3ccd(%rip), %rsi      # 0x5147
leaq 0x20(%rsp), %rdi
callq 0x28a6
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1ba3
testl %eax, %eax
jne 0x18e7
movq %rsp, %rdi
leaq 0x20(%rsp), %rsi
callq 0x1ba3
testl %eax, %eax
jne 0x1906
xorl %r15d, %r15d
callq 0x10e0
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 0x10e0
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 0x10e0
movl %eax, %ebx
callq 0x10e0
movl %r12d, %r14d
negl %r14d
testb $0x1, %al
cmovel %r12d, %r14d
callq 0x10e0
movl %ebp, %r13d
negl %r13d
testb $0x1, %al
cmovel %ebp, %r13d
movq %rsp, %rbp
movq %rbp, %rdi
movl %r14d, %esi
callq 0x28b0
leaq 0x40(%rsp), %rdi
movl %r13d, %esi
callq 0x28b0
leal (%r14,%r13), %esi
leaq 0x80(%rsp), %rdi
callq 0x28b0
movl %r14d, %esi
subl %r13d, %esi
leaq 0x98(%rsp), %rdi
callq 0x28b0
movl %r13d, %esi
imull %r14d, %esi
leaq 0xb0(%rsp), %rdi
callq 0x28b0
testl %r13d, %r13d
je 0x15ae
movl %r14d, %eax
cwtd
idivw %r13w
movl %edx, %ebp
movswl %ax, %esi
leaq 0xc8(%rsp), %rdi
callq 0x28b0
movswl %bp, %esi
movq %rsp, %rbp
leaq 0xe0(%rsp), %rdi
callq 0x28b0
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
movl %r12d, %eax
negl %eax
cmovsl %r12d, %eax
cvtsi2sd %eax, %xmm0
sqrtsd %xmm0, %xmm0
cvttsd2si %xmm0, %esi
leaq 0xf8(%rsp), %rdi
callq 0x28b0
movl %r14d, %edi
movl %r13d, %esi
callq 0x1a13
leaq 0x110(%rsp), %rdi
movl %eax, %esi
callq 0x28b0
leaq 0x20(%rsp), %r12
movq %r12, %rdi
movq %rbp, %rsi
callq 0x1c42
movq %rbp, %rdi
movq %rbp, %rsi
movl %ebx, %edx
callq 0x2e85
movq %rbp, %rdi
movq %rbp, %rsi
movl %ebx, %edx
callq 0x2ed1
movq %rbp, %rdi
movq %r12, %rsi
callq 0x1ba3
testl %eax, %eax
jne 0x17d0
leaq 0x170(%rsp), %rdi
movq %rbp, %rsi
leaq 0x40(%rsp), %rbx
movq %rbx, %rdx
callq 0x2a83
leaq 0x188(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x2a92
leaq 0x1a0(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x2647
leaq 0x1b8(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x32f1
leaq 0x1d0(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x332e
leaq 0x1e8(%rsp), %rdi
movq %rbp, %rsi
callq 0x352b
leaq 0x200(%rsp), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x336e
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 0x172f
leaq 0xf0(%rbx), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x1ba3
testl %eax, %eax
je 0x171c
leaq 0x3a6c(%rip), %rdi      # 0x5176
movl %r15d, %esi
movl %ebp, %edx
movl %r14d, %ecx
movl %r13d, %r8d
xorl %eax, %eax
callq 0x1050
movq %rbx, %rdi
movq %r12, %rsi
callq 0x1ba3
testl %eax, %eax
jne 0x17b1
incq %rbp
addq $0x18, %rbx
cmpq $0x7, %rbp
jne 0x16da
incl %r15d
cmpl $0x3039, %r15d          # imm = 0x3039
jne 0x14af
movq %rsp, %rdi
callq 0x1ac9
leaq 0x40(%rsp), %rdi
callq 0x1ac9
leaq 0x20(%rsp), %rdi
callq 0x1ac9
leaq 0x60(%rsp), %rdi
callq 0x1ac9
xorl %ebx, %ebx
leaq (%rsp,%rbx), %rdi
addq $0x80, %rdi
callq 0x1ac9
addq $0x18, %rbx
cmpq $0x1e0, %rbx            # imm = 0x1E0
jne 0x1774
leaq 0x3a27(%rip), %rdi      # 0x51bf
callq 0x1040
xorl %eax, %eax
addq $0x10268, %rsp          # imm = 0x10268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x39e4(%rip), %rdi      # 0x519c
leaq 0x38bc(%rip), %rsi      # 0x507b
leaq 0x38bd(%rip), %rcx      # 0x5083
movl $0x6b, %edx
callq 0x1060
leaq 0x3989(%rip), %rdi      # 0x5160
leaq 0x389d(%rip), %rsi      # 0x507b
leaq 0x389e(%rip), %rcx      # 0x5083
movl $0x5c, %edx
callq 0x1060
leaq 0x386f(%rip), %rdi      # 0x5065
leaq 0x387e(%rip), %rsi      # 0x507b
leaq 0x387f(%rip), %rcx      # 0x5083
movl $0x19, %edx
callq 0x1060
leaq 0x3879(%rip), %rdi      # 0x508e
leaq 0x385f(%rip), %rsi      # 0x507b
leaq 0x3860(%rip), %rcx      # 0x5083
movl $0x27, %edx
callq 0x1060
leaq 0x3870(%rip), %rdi      # 0x50a4
leaq 0x3840(%rip), %rsi      # 0x507b
leaq 0x3841(%rip), %rcx      # 0x5083
movl $0x2c, %edx
callq 0x1060
leaq 0x3858(%rip), %rdi      # 0x50ab
leaq 0x3821(%rip), %rsi      # 0x507b
leaq 0x3822(%rip), %rcx      # 0x5083
movl $0x2f, %edx
callq 0x1060
leaq 0x3867(%rip), %rdi      # 0x50d9
leaq 0x3802(%rip), %rsi      # 0x507b
leaq 0x3803(%rip), %rcx      # 0x5083
movl $0x34, %edx
callq 0x1060
leaq 0x3870(%rip), %rdi      # 0x5101
leaq 0x37e3(%rip), %rsi      # 0x507b
leaq 0x37e4(%rip), %rcx      # 0x5083
movl $0x37, %edx
callq 0x1060
leaq 0x3869(%rip), %rdi      # 0x5119
leaq 0x37c4(%rip), %rsi      # 0x507b
leaq 0x37c5(%rip), %rcx      # 0x5083
movl $0x39, %edx
callq 0x1060
leaq 0x3861(%rip), %rdi      # 0x5130
leaq 0x37a5(%rip), %rsi      # 0x507b
leaq 0x37a6(%rip), %rcx      # 0x5083
movl $0x3b, %edx
callq 0x1060
leaq 0x385c(%rip), %rdi      # 0x514a
leaq 0x3786(%rip), %rsi      # 0x507b
leaq 0x3787(%rip), %rcx      # 0x5083
movl $0x40, %edx
callq 0x1060
leaq 0x3853(%rip), %rdi      # 0x5160
leaq 0x3767(%rip), %rsi      # 0x507b
leaq 0x3768(%rip), %rcx      # 0x5083
movl $0x41, %edx
callq 0x1060
nopl (%rax)