// File: /workspace/github_c_makefile_star2_O2/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 0x19a4
leaq 0x40(%rsp), %rdi
callq 0x19a4
leaq 0x20(%rsp), %rdi
callq 0x19a4
leaq 0x60(%rsp), %rdi
callq 0x19a4
xorl %ebx, %ebx
cmpq $0x1e0, %rbx            # imm = 0x1E0
je 0x1244
leaq (%rsp,%rbx), %rdi
addq $0x80, %rdi
callq 0x19a4
addq $0x18, %rbx
jmp 0x1225
leaq 0x2ddd(%rip), %rsi      # 0x4028
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x25b2
leaq 0x2df3(%rip), %rsi      # 0x4050
leaq 0x40(%rsp), %r14
movq %r14, %rdi
callq 0x25b2
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x2fc8
movq %r14, %rdi
movq %r15, %rsi
callq 0x1afc
testl %eax, %eax
jne 0x17a3
leaq 0x2e9a(%rip), %rsi      # 0x412e
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x25b2
leaq 0x40(%rsp), %r14
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0x2609
movq %rbx, %rdi
movq %rbx, %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x2adc
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
movq %rbx, %rdx
callq 0x23cd
movq %r15, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x2794
movq %r15, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x2794
movq %r15, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x2785
movq %rbx, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x2794
leaq 0x60(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
movq %rbx, %rdx
callq 0x23cd
movq %r15, %rdi
movq %r14, %rsi
callq 0x1afc
testl %eax, %eax
jne 0x17bc
leaq 0x2cf1(%rip), %rbx      # 0x4028
movq %rsp, %r14
pushq $0xa
popq %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2537
leaq 0x260(%rsp), %rdi
movl $0x10000, %esi          # imm = 0x10000
movq %r14, %rdx
callq 0x3235
movq %rbx, %rdi
movq %rax, %rsi
callq 0x1090
testl %eax, %eax
jne 0x17d5
movq %rsp, %rbx
movq %rbx, %rdi
movl $0x80000000, %esi       # imm = 0x80000000
callq 0x25ba
movq %rbx, %rdi
callq 0x37ed
ucomisd 0x2c78(%rip), %xmm0     # 0x4008
jne 0x17ee
jp 0x17ee
leaq 0x2d24(%rip), %rsi      # 0x40c7
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x25b2
movq %rbx, %rdi
callq 0x37ed
ucomisd 0x2c52(%rip), %xmm0     # 0x4010
jne 0x180a
jp 0x180a
movq %rsp, %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x25ba
movq %rbx, %rdi
callq 0x37ed
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x1826
jp 0x1826
movq %rsp, %rbx
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0x25ba
movq %rbx, %rdi
callq 0x37ed
ucomisd 0x2c07(%rip), %xmm0     # 0x4018
jne 0x1842
jp 0x1842
movq %rsp, %rbx
pushq $-0x1
popq %rsi
movq %rbx, %rdi
callq 0x25ba
movq %rbx, %rdi
callq 0x37ed
ucomisd 0x2be5(%rip), %xmm0     # 0x4020
jne 0x185e
jp 0x185e
leaq 0x2d4d(%rip), %rsi      # 0x419b
movq %rsp, %rbx
movq %rbx, %rdi
callq 0x25b2
leaq 0x2d5d(%rip), %rsi      # 0x41bd
leaq 0x40(%rsp), %r14
movq %r14, %rdi
callq 0x25b2
leaq 0x2cd3(%rip), %rsi      # 0x4147
leaq 0x20(%rsp), %rdi
callq 0x25b2
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1afc
testl %eax, %eax
jne 0x187a
movq %rsp, %rdi
leaq 0x20(%rsp), %rsi
callq 0x1afc
testl %eax, %eax
jne 0x1896
movq %rsp, %rbp
xorl %r15d, %r15d
cmpl $0x3039, %r15d          # imm = 0x3039
je 0x1706
callq 0x10e0
cltd
movl $0x3039, %ebx           # imm = 0x3039
idivl %ebx
movl %edx, %r13d
callq 0x10e0
cltd
idivl %ebx
movl %edx, %r12d
callq 0x10e0
cltd
movl $0x4d2, %ecx            # imm = 0x4D2
idivl %ecx
movl %edx, %ebx
callq 0x10e0
movl %r13d, %r14d
negl %r14d
testb $0x1, %al
movl %r13d, 0x1c(%rsp)
cmovel %r13d, %r14d
callq 0x10e0
movl %r12d, %r13d
negl %r13d
testb $0x1, %al
cmovel %r12d, %r13d
movq %rbp, %rdi
movl %r14d, %esi
callq 0x25ba
leaq 0x40(%rsp), %rdi
movl %r13d, %esi
callq 0x25ba
leal (%r14,%r13), %esi
leaq 0x80(%rsp), %rdi
callq 0x25ba
movl %r14d, %esi
subl %r13d, %esi
leaq 0x98(%rsp), %rdi
callq 0x25ba
movl %r13d, %esi
imull %r14d, %esi
leaq 0xb0(%rsp), %rdi
callq 0x25ba
testl %r13d, %r13d
je 0x158c
movl %r14d, %eax
cwtd
idivw %r13w
movl %edx, %r12d
movswl %ax, %esi
leaq 0xc8(%rsp), %rdi
callq 0x25ba
movswl %r12w, %esi
leaq 0xe0(%rsp), %rdi
callq 0x25ba
movl 0x1c(%rsp), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
cvtsi2sd %eax, %xmm0
sqrtsd %xmm0, %xmm0
cvttsd2si %xmm0, %esi
leaq 0xf8(%rsp), %rdi
callq 0x25ba
movl %r14d, %edi
movl %r13d, %esi
callq 0x1991
leaq 0x110(%rsp), %rdi
movl %eax, %esi
callq 0x25ba
leaq 0x20(%rsp), %rbp
movq %rbp, %rdi
movq %rsp, %r12
movq %r12, %rsi
callq 0x1b99
movq %r12, %rdi
movq %r12, %rsi
movl %ebx, %edx
callq 0x2adc
movq %r12, %rdi
movq %r12, %rsi
movl %ebx, %edx
callq 0x2b28
movq %r12, %rdi
movq %rbp, %rsi
callq 0x1afc
testl %eax, %eax
jne 0x178a
leaq 0x170(%rsp), %rdi
movq %r12, %rsi
leaq 0x40(%rsp), %rbx
movq %rbx, %rdx
callq 0x2785
leaq 0x188(%rsp), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x2794
leaq 0x1a0(%rsp), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x23cd
leaq 0x1b8(%rsp), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x2df7
leaq 0x1d0(%rsp), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x2e31
leaq 0x1e8(%rsp), %rdi
movq %r12, %rsi
callq 0x2fc8
leaq 0x200(%rsp), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x2e6e
leaq 0x80(%rsp), %rbx
xorl %ebp, %ebp
cmpq $0x7, %rbp
je 0x16fb
testl %r13d, %r13d
sete %al
leal -0x3(%rbp), %ecx
cmpl $0x2, %ecx
setb %cl
testb %cl, %al
jne 0x16f2
leaq 0xf0(%rbx), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x1afc
testl %eax, %eax
je 0x16e3
leaq 0x2aa5(%rip), %rdi      # 0x4176
movl %r15d, %esi
movl %ebp, %edx
movl %r14d, %ecx
movl %r13d, %r8d
xorl %eax, %eax
callq 0x1050
movq %rbx, %rdi
movq %r12, %rsi
callq 0x1afc
testl %eax, %eax
jne 0x176d
incq %rbp
addq $0x18, %rbx
jmp 0x169b
incl %r15d
movq %rsp, %rbp
jmp 0x14ac
movq %rsp, %rdi
callq 0x1a26
leaq 0x40(%rsp), %rdi
callq 0x1a26
leaq 0x20(%rsp), %rdi
callq 0x1a26
leaq 0x60(%rsp), %rdi
callq 0x1a26
xorl %ebx, %ebx
cmpq $0x1e0, %rbx            # imm = 0x1E0
je 0x174d
leaq (%rsp,%rbx), %rdi
addq $0x80, %rdi
callq 0x1a26
addq $0x18, %rbx
jmp 0x172e
leaq 0x2a6b(%rip), %rdi      # 0x41bf
callq 0x1040
xorl %eax, %eax
addq $0x10268, %rsp          # imm = 0x10268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2a28(%rip), %rdi      # 0x419c
leaq 0x2900(%rip), %rsi      # 0x407b
leaq 0x2901(%rip), %rcx      # 0x4083
pushq $0x6b
popq %rdx
callq 0x1060
leaq 0x29cf(%rip), %rdi      # 0x4160
leaq 0x28e3(%rip), %rsi      # 0x407b
leaq 0x28e4(%rip), %rcx      # 0x4083
pushq $0x5c
jmp 0x1784
leaq 0x28bb(%rip), %rdi      # 0x4065
leaq 0x28ca(%rip), %rsi      # 0x407b
leaq 0x28cb(%rip), %rcx      # 0x4083
pushq $0x19
jmp 0x1784
leaq 0x28cb(%rip), %rdi      # 0x408e
leaq 0x28b1(%rip), %rsi      # 0x407b
leaq 0x28b2(%rip), %rcx      # 0x4083
pushq $0x27
jmp 0x1784
leaq 0x28c8(%rip), %rdi      # 0x40a4
leaq 0x2898(%rip), %rsi      # 0x407b
leaq 0x2899(%rip), %rcx      # 0x4083
pushq $0x2c
jmp 0x1784
leaq 0x28b6(%rip), %rdi      # 0x40ab
leaq 0x287f(%rip), %rsi      # 0x407b
leaq 0x2880(%rip), %rcx      # 0x4083
pushq $0x2f
jmp 0x1784
leaq 0x28c8(%rip), %rdi      # 0x40d9
leaq 0x2863(%rip), %rsi      # 0x407b
leaq 0x2864(%rip), %rcx      # 0x4083
pushq $0x34
jmp 0x1784
leaq 0x28d4(%rip), %rdi      # 0x4101
leaq 0x2847(%rip), %rsi      # 0x407b
leaq 0x2848(%rip), %rcx      # 0x4083
pushq $0x37
jmp 0x1784
leaq 0x28d0(%rip), %rdi      # 0x4119
leaq 0x282b(%rip), %rsi      # 0x407b
leaq 0x282c(%rip), %rcx      # 0x4083
pushq $0x39
jmp 0x1784
leaq 0x28cb(%rip), %rdi      # 0x4130
leaq 0x280f(%rip), %rsi      # 0x407b
leaq 0x2810(%rip), %rcx      # 0x4083
pushq $0x3b
jmp 0x1784
leaq 0x28c9(%rip), %rdi      # 0x414a
leaq 0x27f3(%rip), %rsi      # 0x407b
leaq 0x27f4(%rip), %rcx      # 0x4083
pushq $0x40
jmp 0x1784
leaq 0x28c3(%rip), %rdi      # 0x4160
leaq 0x27d7(%rip), %rsi      # 0x407b
leaq 0x27d8(%rip), %rcx      # 0x4083
pushq $0x41
jmp 0x1784
nop