// File: /workspace/github_c_makefile_star2_O3/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 0x42b7
movq (%rbx), %rsi
leaq 0x736b(%rip), %rdi      # 0xb5b0
xorl %eax, %eax
callq 0x1060
movq (%rbx), %rsi
leaq 0x736b(%rip), %rdi      # 0xb5c1
xorl %eax, %eax
callq 0x1060
movq (%rbx), %rsi
leaq 0x7371(%rip), %rdi      # 0xb5d8
xorl %eax, %eax
callq 0x1060
movq (%rbx), %rsi
leaq 0x7373(%rip), %rdi      # 0xb5eb
xorl %eax, %eax
callq 0x1060
movq (%rbx), %rsi
leaq 0x737b(%rip), %r14      # 0xb604
movq %r14, %rdi
xorl %eax, %eax
callq 0x1060
movq (%rbx), %rsi
movq %r14, %rdi
xorl %eax, %eax
callq 0x1060
leaq 0x75a0(%rip), %rdi      # 0xb847
callq 0x1030
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
jmp 0x49cb
movq 0x8(%rbx), %rdi
movzbl (%rdi), %ecx
leal -0x61(%rcx), %eax
cmpl $0xb, %eax
ja 0x433a
leaq 0x72b3(%rip), %rcx      # 0xb580
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x3, %r14d
jne 0x483c
movq 0x10(%rbx), %rdi
xorl %r14d, %r14d
xorl %esi, %esi
callq 0x1040
movsd %xmm0, 0x60(%rsp)
movq 0x10(%rbx), %rdi
callq 0x2d79
movsd %xmm0, 0x10(%rsp)
movsd 0x60(%rsp), %xmm0
ucomisd 0x10(%rsp), %xmm0
jne 0x4317
jnp 0x49cb
movq 0x10(%rbx), %rsi
movsd 0x60(%rsp), %xmm0
movsd 0x10(%rsp), %xmm1
leaq 0x7406(%rip), %rdi      # 0xb734
movb $0x2, %al
callq 0x1060
jmp 0x49cb
cmpl $0x4c, %ecx
jne 0x436b
movq 0x10(%rbx), %rdi
callq 0x2cf1
movq %rax, %r15
leaq 0x20(%rsp), %r12
movq %rax, %rdi
movq %r12, %rsi
callq 0x1c4a
movq 0x10(%rbx), %rsi
leaq 0x7349(%rip), %rdi      # 0xb6af
jmp 0x4432
xorl %esi, %esi
callq 0x1040
cmpl $0x2, %r14d
movsd %xmm0, (%rsp)
jne 0x4531
xorpd %xmm1, %xmm1
leaq 0x60(%rsp), %r14
movapd %xmm1, 0x30(%r14)
movapd %xmm1, 0x20(%r14)
movapd %xmm1, 0x10(%r14)
movapd %xmm1, (%r14)
leaq 0x73fa(%rip), %rdx      # 0xb7a2
movl $0x40, %esi
movq %r14, %rdi
movb $0x1, %al
callq 0x1070
leaq 0x20(%rsp), %r15
movsd (%rsp), %xmm0
movq %r15, %rdi
callq 0x1d15
movq %r15, %rdi
movq %r14, %rsi
callq 0x1090
testl %eax, %eax
je 0x49c8
movq 0x8(%rbx), %rsi
leaq 0x73c2(%rip), %rdi      # 0xb7a9
leaq 0x60(%rsp), %rdx
xorl %eax, %eax
callq 0x1060
leaq 0x730a(%rip), %rdi      # 0xb704
leaq 0x20(%rsp), %rsi
xorl %eax, %eax
callq 0x1060
jmp 0x49c8
movq 0x10(%rbx), %rdi
callq 0x2c29
movq %rax, %r15
leaq 0x20(%rsp), %r12
movq %rax, %rdi
movq %r12, %rsi
callq 0x1542
movq 0x10(%rbx), %rsi
leaq 0x721d(%rip), %rdi      # 0xb64f
xorl %r14d, %r14d
movq %r15, %rdx
movq %r12, %rcx
xorl %eax, %eax
callq 0x1060
jmp 0x49cb
movq 0x10(%rbx), %rdi
callq 0x2c93
movl %eax, %ebp
leaq 0x20(%rsp), %r15
movl %eax, %edi
movq %r15, %rsi
callq 0x1a90
movq 0x10(%rbx), %rsi
leaq 0x7213(%rip), %rdi      # 0xb67f
jmp 0x451d
movq 0x10(%rbx), %rdi
callq 0x2d79
movsd %xmm0, (%rsp)
movq 0x10(%rbx), %rsi
leaq 0x7257(%rip), %rdi      # 0xb6e1
movb $0x1, %al
callq 0x1060
leaq 0x20(%rsp), %rbx
movsd (%rsp), %xmm0
movq %rbx, %rdi
callq 0x1d15
leaq 0x725a(%rip), %rdi      # 0xb704
xorl %r14d, %r14d
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1060
movsd (%rsp), %xmm0
movq %rbx, %rdi
callq 0x2e12
leaq 0x7249(%rip), %rdi      # 0xb714
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1060
movsd (%rsp), %xmm0
movq %rbx, %rdi
callq 0x34f5
leaq 0x723b(%rip), %rdi      # 0xb724
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1060
jmp 0x49cb
movq 0x10(%rbx), %rdi
callq 0x2bcc
movl %eax, %ebp
leaq 0x20(%rsp), %r15
movl %eax, %edi
movq %r15, %rsi
callq 0x11b9
movq 0x10(%rbx), %rsi
leaq 0x7104(%rip), %rdi      # 0xb621
xorl %r14d, %r14d
movl %ebp, %edx
movq %r15, %rcx
xorl %eax, %eax
callq 0x1060
jmp 0x49cb
movq 0x10(%rbx), %rdi
callq 0x10b0
movl %eax, %ebp
leaq 0x60(%rsp), %r14
movl $0x1, %edi
movq %r14, %rsi
callq 0x1050
movl $0xfffffc18, %ecx       # imm = 0xFFFFFC18
imull (%r14), %ecx
movabsq $-0x431bde82d7b634db, %rax # imm = 0xBCE4217D2849CB25
imulq 0x8(%r14)
movq %rdx, %r15
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %r15
addl %eax, %r15d
addl %ecx, %r15d
testl %ebp, %ebp
jle 0x45a8
leaq 0x721e(%rip), %r14      # 0xb7a2
leaq 0x20(%rsp), %r12
movl %ebp, %r13d
movl $0x40, %esi
movq %r12, %rdi
movq %r14, %rdx
movsd (%rsp), %xmm0
movb $0x1, %al
callq 0x1070
decl %r13d
jne 0x458c
leaq 0x60(%rsp), %r14
movl $0x1, %edi
movq %r14, %rsi
callq 0x1050
imull $0x3e8, (%r14), %ecx    # imm = 0x3E8
movabsq $0x431bde82d7b634db, %r12 # imm = 0x431BDE82D7B634DB
movq %r12, %rax
imulq 0x8(%r14)
movq %rdx, %r14
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %r14
addl %eax, %r14d
addl %ecx, %r14d
addl %r15d, %r14d
movq 0x8(%rbx), %rsi
leaq 0x71d4(%rip), %rdi      # 0xb7c8
movsd (%rsp), %xmm0
movl %r14d, %edx
movb $0x1, %al
callq 0x1060
leaq 0x60(%rsp), %rbx
movl $0x1, %edi
movq %rbx, %rsi
callq 0x1050
imull $0x3e8, (%rbx), %ecx    # imm = 0x3E8
movq %r12, %rax
imulq 0x8(%rbx)
movq %rdx, %rbx
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %rbx
addl %eax, %ebx
addl %ecx, %ebx
testl %ebp, %ebp
jle 0x4652
leaq 0x20(%rsp), %r15
movl %ebp, %r12d
movsd (%rsp), %xmm0
movq %r15, %rdi
callq 0x1d15
decl %r12d
jne 0x4640
leaq 0x60(%rsp), %r12
movl $0x1, %edi
movq %r12, %rsi
callq 0x1050
imull $0x3e8, (%r12), %ecx    # imm = 0x3E8
movabsq $0x431bde82d7b634db, %r15 # imm = 0x431BDE82D7B634DB
movq %r15, %rax
imulq 0x8(%r12)
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %rdx
addl %eax, %edx
addl %ecx, %edx
movl %r14d, %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
mulsd 0x6ed8(%rip), %xmm0     # 0xb578
movsd %xmm0, 0x8(%rsp)
xorpd %xmm0, %xmm0
subl %ebx, %edx
je 0x46bd
cvtsi2sd %rdx, %xmm1
movsd 0x8(%rsp), %xmm0
divsd %xmm1, %xmm0
leaq 0x712c(%rip), %rdi      # 0xb7f0
leaq 0x20(%rsp), %rsi
movb $0x1, %al
callq 0x1060
leaq 0x60(%rsp), %rbx
movl $0x1, %edi
movq %rbx, %rsi
callq 0x1050
imull $0x3e8, (%rbx), %ecx    # imm = 0x3E8
movq %r15, %rax
imulq 0x8(%rbx)
movq %rdx, %rbx
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %rbx
addl %eax, %ebx
addl %ecx, %ebx
testl %ebp, %ebp
jle 0x471f
leaq 0x20(%rsp), %r14
movl %ebp, %r15d
movsd (%rsp), %xmm0
movq %r14, %rdi
callq 0x2e12
decl %r15d
jne 0x470d
leaq 0x60(%rsp), %r15
movl $0x1, %edi
movq %r15, %rsi
callq 0x1050
imull $0x3e8, (%r15), %ecx    # imm = 0x3E8
movabsq $0x431bde82d7b634db, %r14 # imm = 0x431BDE82D7B634DB
movq %r14, %rax
imulq 0x8(%r15)
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %rdx
addl %eax, %edx
addl %ecx, %edx
xorpd %xmm0, %xmm0
subl %ebx, %edx
je 0x4772
xorps %xmm1, %xmm1
cvtsi2sd %rdx, %xmm1
movsd 0x8(%rsp), %xmm0
divsd %xmm1, %xmm0
leaq 0x7094(%rip), %rdi      # 0xb80d
leaq 0x20(%rsp), %rsi
movb $0x1, %al
callq 0x1060
leaq 0x60(%rsp), %rbx
movl $0x1, %edi
movq %rbx, %rsi
callq 0x1050
imull $0x3e8, (%rbx), %ecx    # imm = 0x3E8
movq %r14, %rax
imulq 0x8(%rbx)
movq %rdx, %rbx
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %rbx
addl %eax, %ebx
addl %ecx, %ebx
testl %ebp, %ebp
jle 0x47d0
leaq 0x20(%rsp), %r14
movsd (%rsp), %xmm0
movq %r14, %rdi
callq 0x34f5
decl %ebp
jne 0x47bf
leaq 0x60(%rsp), %r14
movl $0x1, %edi
movq %r14, %rsi
callq 0x1050
imull $0x3e8, (%r14), %ecx    # imm = 0x3E8
movabsq $0x431bde82d7b634db, %rax # imm = 0x431BDE82D7B634DB
imulq 0x8(%r14)
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %rdx
addl %eax, %edx
addl %ecx, %edx
xorpd %xmm0, %xmm0
subl %ebx, %edx
je 0x4824
xorps %xmm0, %xmm0
cvtsi2sd %rdx, %xmm0
movsd 0x8(%rsp), %xmm1
divsd %xmm0, %xmm1
movapd %xmm1, %xmm0
leaq 0x6fff(%rip), %rdi      # 0xb82a
leaq 0x20(%rsp), %rsi
movb $0x1, %al
callq 0x1060
jmp 0x49c8
movq 0x18(%rbx), %rdi
callq 0x10b0
movl %eax, %ebp
xorpd %xmm0, %xmm0
movapd %xmm0, 0x90(%rsp)
movapd %xmm0, 0x80(%rsp)
movapd %xmm0, 0x70(%rsp)
movapd %xmm0, 0x60(%rsp)
leaq 0x10(%rsp), %r15
movl $0x1, %edi
movq %r15, %rsi
callq 0x1050
movl $0xfffffc18, %r12d      # imm = 0xFFFFFC18
movabsq $-0x431bde82d7b634db, %rax # imm = 0xBCE4217D2849CB25
imulq 0x8(%r15)
movq %rdx, %r14
imull (%r15), %r12d
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %r14
addl %eax, %r14d
testl %ebp, %ebp
jle 0x48c4
movl %ebp, %r15d
movq 0x10(%rbx), %rdi
xorl %esi, %esi
callq 0x1040
movsd %xmm0, 0xb0(%rsp)
decl %r15d
jne 0x48ab
addl %r12d, %r14d
leaq 0x10(%rsp), %r15
movl $0x1, %edi
movq %r15, %rsi
callq 0x1050
imull $0x3e8, (%r15), %ecx    # imm = 0x3E8
movabsq $0x431bde82d7b634db, %rax # imm = 0x431BDE82D7B634DB
imulq 0x8(%r15)
movq %rdx, %r15
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %r15
addl %eax, %r15d
addl %ecx, %r15d
testl %ebp, %ebp
jle 0x491c
movq 0x10(%rbx), %rdi
callq 0x2d79
movsd %xmm0, 0xa8(%rsp)
decl %ebp
jne 0x4906
leaq 0x10(%rsp), %r12
movl $0x1, %edi
movq %r12, %rsi
callq 0x1050
imull $0x3e8, (%r12), %ecx    # imm = 0x3E8
movabsq $0x431bde82d7b634db, %rax # imm = 0x431BDE82D7B634DB
imulq 0x8(%r12)
movq %rdx, %r12
movq %rdx, %rax
shrq $0x3f, %rax
shrq $0x12, %r12
addl %eax, %r12d
addl %ecx, %r12d
movsd 0xb0(%rsp), %xmm0
leaq 0x20(%rsp), %r13
movq %r13, %rdi
callq 0x1d15
movsd 0xa8(%rsp), %xmm0
leaq 0x60(%rsp), %rbp
movq %rbp, %rdi
callq 0x1d15
movq 0x10(%rbx), %rsi
addl %r15d, %r14d
xorpd %xmm0, %xmm0
subl %r15d, %r12d
je 0x49ae
xorps %xmm0, %xmm0
cvtsi2sd %r14, %xmm0
mulsd 0x6bd3(%rip), %xmm0     # 0xb578
cvtsi2sd %r12, %xmm1
divsd %xmm1, %xmm0
leaq 0x6daf(%rip), %rdi      # 0xb764
movq %r13, %rdx
movl %r14d, %ecx
movq %rbp, %r8
movl %r12d, %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