// File: /workspace/github_c_makefile_star2_O2/lengjingzju[P]json/jnum_test.c
// Function: main
int main(int argc, char *argv[])
{
    char buf[64] = {0};

    if (argc != 2 && argc != 3 && argc != 4) {
        printf("Usage: %s <num>\n", argv[0]);
        printf("       %s <num> <cnt>\n", argv[0]);
        printf("       %s a <num>\n", argv[0]);
        printf("       %s a <num> <cnt>\n", argv[0]);
        printf("       %s <i/l/h/L/d> <num>\n", argv[0]);
        printf("       %s <i/l/h/L/d> <num>\n", argv[0]);
        printf("a: atod, i: itoa, l: ltoa, h: htoa, L: lhtoa, d or default: dtoa/grisu2/dragonbox/...\n");
        return -1;
    }

    switch (*argv[1]) {
    case 'i':
        {
            int32_t d = jnum_atoi(argv[2]);
            jnum_itoa(d, buf);
            printf("original  : %s\nprintf    : %d\njnum      : %s\n", argv[2], d, buf);
            break;
        }
    case 'l':
        {
            int64_t d = jnum_atol(argv[2]);
            jnum_ltoa(d, buf);
            printf("original  : %s\nprintf    : %lld\njnum      : %s\n", argv[2], (long long)d, buf);
            break;
        }
    case 'h':
        {
            uint32_t d = jnum_atoh(argv[2]);
            jnum_htoa(d, buf);
            printf("original  : %s\nprintf    : 0x%x\njnum      : %s\n", argv[2], d, buf);
            break;
        }
    case 'L':
        {
            uint64_t d = jnum_atolh(argv[2]);
            jnum_lhtoa(d, buf);
            printf("original  : %s\nprintf    : 0x%llx\njnum      : %s\n", argv[2], (unsigned long long)d, buf);
            break;
        }
    case 'd':
        {
            double d = jnum_atod(argv[2]);
            printf("original  : %s\nprintf    : %0.16g\n", argv[2], d);
            jnum_dtoa(d, buf);
            printf("ldouble   : %s\n", buf);
            grisu2_dtoa(d, buf);
            printf("grisu2    : %s\n", buf);
            dragonbox_dtoa(d, buf);
            printf("dragonbox : %s\n", buf);
            break;
        }

    case 'a':
        if (argc == 3) {
            volatile double d1, d2;
            d1 = strtod(argv[2], NULL);
            d2 = jnum_atod(argv[2]);
            if (d1 != d2)
                printf("----%s----\nstrtod:    %0.16g\njnum_atod: %0.16g\n", argv[2], d1, d2);
        } else {
            int i;
            int cnt = atoi(argv[3]);
            volatile double d1, d2;
            unsigned int ms1, ms2, ms3;
            char tmp[64] = {0};

            ms1 = _system_ms_get();
            for (i = 0; i < cnt; ++i) {
                d1 = strtod(argv[2], NULL);
            }
            ms2 = _system_ms_get();
            for (i = 0; i < cnt; ++i) {
                d2 = jnum_atod(argv[2]);
            }
            ms3 = _system_ms_get();

            jnum_dtoa(d1, buf);
            jnum_dtoa(d2, tmp);
            printf("original  : %s\nstrtod:    %s %ums\njnum_atod: %s %ums\t%.0lf%%\n", argv[2], buf, ms2 - ms1, tmp, ms3 - ms2,
                 ms3 - ms2 ? 100.0 * (ms2 - ms1) / (ms3 - ms2) : 0);
        }
        break;

    default:
        if (argc == 2) {
            double d = strtod(argv[1], NULL);
            char tmp[64] = {0};

            snprintf(tmp, sizeof(tmp), "%0.16g", d);
            jnum_dtoa(d, buf);
            if (strcmp(buf, tmp)) {
                printf("original  : %s\nprintf    : %s\n", argv[1], tmp);
                printf("ldouble   : %s\n", buf);
            }
        } else {
            int i;
            double d = strtod(argv[1], NULL);
            int cnt = atoi(argv[2]);
            unsigned int ms, ms1, ms2, ms3;

            ms1 = _system_ms_get();
            for (i = 0; i < cnt; ++i) {
                snprintf(buf, sizeof(buf), "%0.16g", d);
            }
            ms2 = _system_ms_get();
            ms = ms2 - ms1;
            printf("original  : %s\nprintf    : %0.16g\t%ums\n", argv[1], d, ms);

            ms1 = _system_ms_get();
            for (i = 0; i < cnt; ++i) {
                jnum_dtoa(d, buf);
            }
            ms2 = _system_ms_get();
            ms3 = ms2 - ms1;
            printf("ldouble   : %s\t%ums\t%.0lf%%\n", buf, ms3, ms3 ? 100.0 * ms / ms3 : 0);

            ms1 = _system_ms_get();
            for (i = 0; i < cnt; ++i) {
                grisu2_dtoa(d, buf);
            }
            ms2 = _system_ms_get();
            ms3 = ms2 - ms1;
            printf("grisu2    : %s\t%ums\t%.0lf%%\n", buf, ms3, ms3 ? 100.0 * ms / ms3 : 0);

            ms1 = _system_ms_get();
            for (i = 0; i < cnt; ++i) {
                dragonbox_dtoa(d, buf);
            }
            ms2 = _system_ms_get();
            ms3 = ms2 - ms1;
            printf("dragonbox : %s\t%ums\t%.0lf%%\n", buf, ms3, ms3 ? 100.0 * ms / ms3 : 0);
        }
        break;
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rsi, %rbx
movl %edi, %r14d
xorpd %xmm0, %xmm0
movapd %xmm0, 0x50(%rsp)
movapd %xmm0, 0x40(%rsp)
movapd %xmm0, 0x30(%rsp)
movapd %xmm0, 0x20(%rsp)
leal -0x5(%r14), %eax
cmpl $-0x4, %eax
ja 0x3540
movq (%rbx), %rsi
leaq 0x70e0(%rip), %rdi      # 0xa5b0
xorl %eax, %eax
callq 0x1060
movq (%rbx), %rsi
leaq 0x70e0(%rip), %rdi      # 0xa5c1
xorl %eax, %eax
callq 0x1060
movq (%rbx), %rsi
leaq 0x70e6(%rip), %rdi      # 0xa5d8
xorl %eax, %eax
callq 0x1060
movq (%rbx), %rsi
leaq 0x70e8(%rip), %rdi      # 0xa5eb
xorl %eax, %eax
callq 0x1060
movq (%rbx), %rsi
leaq 0x70f0(%rip), %r14      # 0xa604
movq %r14, %rdi
xorl %eax, %eax
callq 0x1060
movq (%rbx), %rsi
movq %r14, %rdi
xorl %eax, %eax
callq 0x1060
leaq 0x7315(%rip), %rdi      # 0xa847
callq 0x1030
pushq $-0x1
popq %r14
jmp 0x3a3e
movq 0x8(%rbx), %rdi
movzbl (%rdi), %ecx
leal -0x61(%rcx), %eax
cmpl $0xb, %eax
ja 0x35c3
leaq 0x702a(%rip), %rcx      # 0xa580
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x3, %r14d
jne 0x3952
movq 0x10(%rbx), %rdi
xorl %r14d, %r14d
xorl %esi, %esi
callq 0x1040
movsd %xmm0, 0x70(%rsp)
movq 0x10(%rbx), %rdi
callq 0x23ba
movsd %xmm0, 0x18(%rsp)
movsd 0x70(%rsp), %xmm0
ucomisd 0x18(%rsp), %xmm0
jne 0x35a0
jnp 0x3a3e
movq 0x10(%rbx), %rsi
movsd 0x70(%rsp), %xmm0
movsd 0x18(%rsp), %xmm1
leaq 0x717d(%rip), %rdi      # 0xa734
movb $0x2, %al
callq 0x1060
jmp 0x3a3e
cmpl $0x4c, %ecx
jne 0x35f4
movq 0x10(%rbx), %rdi
callq 0x2347
movq %rax, %r15
leaq 0x20(%rsp), %r12
movq %rax, %rdi
movq %r12, %rsi
callq 0x155b
movq 0x10(%rbx), %rsi
leaq 0x70c0(%rip), %rdi      # 0xa6af
jmp 0x36bd
xorl %ebp, %ebp
xorl %esi, %esi
callq 0x1040
cmpl $0x2, %r14d
movsd %xmm0, 0x8(%rsp)
jne 0x37c0
xorpd %xmm1, %xmm1
leaq 0x70(%rsp), %r14
movapd %xmm1, 0x30(%r14)
movapd %xmm1, 0x20(%r14)
movapd %xmm1, 0x10(%r14)
movapd %xmm1, (%r14)
leaq 0x716e(%rip), %rdx      # 0xa7a2
pushq $0x40
popq %rsi
movq %r14, %rdi
movb $0x1, %al
callq 0x1070
leaq 0x20(%rsp), %r15
movsd 0x8(%rsp), %xmm0
movq %r15, %rdi
callq 0x15ce
movq %r15, %rdi
movq %r14, %rsi
callq 0x1090
testl %eax, %eax
je 0x3a3b
movq 0x8(%rbx), %rsi
leaq 0x7137(%rip), %rdi      # 0xa7a9
leaq 0x70(%rsp), %rdx
xorl %eax, %eax
callq 0x1060
leaq 0x707f(%rip), %rdi      # 0xa704
leaq 0x20(%rsp), %rsi
xorl %eax, %eax
callq 0x1060
jmp 0x3a3b
movq 0x10(%rbx), %rdi
callq 0x22a9
movq %rax, %r15
leaq 0x20(%rsp), %r12
movq %rax, %rdi
movq %r12, %rsi
callq 0x1395
movq 0x10(%rbx), %rsi
leaq 0x6f92(%rip), %rdi      # 0xa64f
xorl %r14d, %r14d
movq %r15, %rdx
movq %r12, %rcx
xorl %eax, %eax
callq 0x1060
jmp 0x3a3e
movq 0x10(%rbx), %rdi
callq 0x22fe
movl %eax, %ebp
leaq 0x20(%rsp), %r15
movl %eax, %edi
movq %r15, %rsi
callq 0x14eb
movq 0x10(%rbx), %rsi
leaq 0x6f88(%rip), %rdi      # 0xa67f
jmp 0x37ac
movq 0x10(%rbx), %rdi
callq 0x23ba
movsd %xmm0, 0x8(%rsp)
movq 0x10(%rbx), %rsi
leaq 0x6fcb(%rip), %rdi      # 0xa6e1
movb $0x1, %al
callq 0x1060
leaq 0x20(%rsp), %rbx
movsd 0x8(%rsp), %xmm0
movq %rbx, %rdi
callq 0x15ce
leaq 0x6fcd(%rip), %rdi      # 0xa704
xorl %r14d, %r14d
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1060
movsd 0x8(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2619
leaq 0x6fbb(%rip), %rdi      # 0xa714
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1060
movsd 0x8(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2b96
leaq 0x6fac(%rip), %rdi      # 0xa724
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1060
jmp 0x3a3e
movq 0x10(%rbx), %rdi
callq 0x223b
movl %eax, %ebp
leaq 0x20(%rsp), %r15
movl %eax, %edi
movq %r15, %rsi
callq 0x11b9
movq 0x10(%rbx), %rsi
leaq 0x6e75(%rip), %rdi      # 0xa621
xorl %r14d, %r14d
movl %ebp, %edx
movq %r15, %rcx
xorl %eax, %eax
callq 0x1060
jmp 0x3a3e
movq 0x10(%rbx), %rdi
callq 0x10b0
movl %eax, %r15d
callq 0x3a53
movl %eax, 0x10(%rsp)
testl %r15d, %r15d
cmovgl %r15d, %ebp
leaq 0x6fbf(%rip), %r15      # 0xa7a2
leaq 0x20(%rsp), %r12
pushq $0x40
popq %r13
movl %ebp, %r14d
subl $0x1, %r14d
movsd 0x8(%rsp), %xmm0
jb 0x380d
movq %r12, %rdi
movq %r13, %rsi
movq %r15, %rdx
movb $0x1, %al
callq 0x1070
jmp 0x37ef
callq 0x3a53
movl %eax, %r15d
subl 0x10(%rsp), %r15d
movq 0x8(%rbx), %rsi
leaq 0x6fa3(%rip), %rdi      # 0xa7c8
movsd 0x8(%rsp), %xmm0
movl %r15d, %edx
movb $0x1, %al
callq 0x1060
callq 0x3a53
movl %eax, %ebx
leaq 0x20(%rsp), %r14
movl %ebp, %r12d
subl $0x1, %r12d
jb 0x385a
movsd 0x8(%rsp), %xmm0
movq %r14, %rdi
callq 0x15ce
jmp 0x3844
callq 0x3a53
movl %r15d, %ecx
cvtsi2sd %rcx, %xmm0
mulsd 0x6d09(%rip), %xmm0     # 0xa578
movsd %xmm0, 0x10(%rsp)
xorpd %xmm0, %xmm0
subl %ebx, %eax
je 0x388c
cvtsi2sd %rax, %xmm1
movsd 0x10(%rsp), %xmm0
divsd %xmm1, %xmm0
leaq 0x6f5d(%rip), %rdi      # 0xa7f0
leaq 0x20(%rsp), %rbx
movq %rbx, %rsi
movl %eax, %edx
movb $0x1, %al
callq 0x1060
callq 0x3a53
movl %eax, %r14d
movl %ebp, %r15d
subl $0x1, %r15d
movsd 0x8(%rsp), %xmm0
jb 0x38c5
movq %rbx, %rdi
callq 0x2619
jmp 0x38af
callq 0x3a53
xorpd %xmm0, %xmm0
subl %r14d, %eax
je 0x38e2
cvtsi2sd %rax, %xmm1
movsd 0x10(%rsp), %xmm0
divsd %xmm1, %xmm0
leaq 0x6f24(%rip), %rdi      # 0xa80d
leaq 0x20(%rsp), %rbx
movq %rbx, %rsi
movl %eax, %edx
movb $0x1, %al
callq 0x1060
callq 0x3a53
movl %eax, %r14d
subl $0x1, %ebp
movsd 0x8(%rsp), %xmm0
jb 0x3917
movq %rbx, %rdi
callq 0x2b96
jmp 0x3902
callq 0x3a53
xorpd %xmm0, %xmm0
subl %r14d, %eax
je 0x3938
cvtsi2sd %rax, %xmm0
movsd 0x10(%rsp), %xmm1
divsd %xmm0, %xmm1
movapd %xmm1, %xmm0
leaq 0x6eeb(%rip), %rdi      # 0xa82a
leaq 0x20(%rsp), %rsi
movl %eax, %edx
movb $0x1, %al
callq 0x1060
jmp 0x3a3b
movq 0x18(%rbx), %rdi
callq 0x10b0
movl %eax, %r14d
xorpd %xmm0, %xmm0
movapd %xmm0, 0xa0(%rsp)
movapd %xmm0, 0x90(%rsp)
movapd %xmm0, 0x80(%rsp)
movapd %xmm0, 0x70(%rsp)
callq 0x3a53
movl %eax, %ebp
xorl %eax, %eax
testl %r14d, %r14d
cmovlel %eax, %r14d
movl %r14d, %r15d
subl $0x1, %r15d
jb 0x39af
movq 0x10(%rbx), %rdi
xorl %esi, %esi
callq 0x1040
movsd %xmm0, 0x18(%rsp)
jmp 0x3996
callq 0x3a53
movl %eax, %r15d
subl $0x1, %r14d
jb 0x39ce
movq 0x10(%rbx), %rdi
callq 0x23ba
movsd %xmm0, 0x68(%rsp)
jmp 0x39b7
callq 0x3a53
movl %eax, %r14d
movsd 0x18(%rsp), %xmm0
leaq 0x20(%rsp), %r12
movq %r12, %rdi
callq 0x15ce
movsd 0x68(%rsp), %xmm0
leaq 0x70(%rsp), %r13
movq %r13, %rdi
callq 0x15ce
movq 0x10(%rbx), %rsi
movl %r15d, %ecx
subl %ebp, %ecx
xorpd %xmm0, %xmm0
subl %r15d, %r14d
je 0x3a24
cvtsi2sd %rcx, %xmm0
mulsd 0x6b5d(%rip), %xmm0     # 0xa578
cvtsi2sd %r14, %xmm1
divsd %xmm1, %xmm0
leaq 0x6d39(%rip), %rdi      # 0xa764
movq %r12, %rdx
movq %r13, %r8
movl %r14d, %r9d
movb $0x1, %al
callq 0x1060
xorl %r14d, %r14d
movl %r14d, %eax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq