// File: ArashPartow[P]exprtk-extras/exprtk_montecarlo_e.cpp
// Function: void monte_carlo_e<double>()
void monte_carlo_e()
{
   typedef exprtk::symbol_table<T> symbol_table_t;
   typedef exprtk::expression<T>   expression_t;
   typedef exprtk::parser<T>       parser_t;

   const std::string monte_carlo_e_program =
      " var max_samples := 10^8;                  "
      " var trials      := 0;                     "
      "                                           "
      " for (var i := 0; i < max_samples; i += 1) "
      " {                                         "
      "    var rand_sum := 0;                     "
      "    repeat                                 "
      "       rand_sum += rnd_01;                 "
      "       trials   += 1;                      "
      "    until (rand_sum > 1);                  "
      " };                                        "
      "                                           "
      " trials / max_samples;                     ";

   rnd_01<T> rnd01;

   symbol_table_t symbol_table;
   symbol_table.add_function("rnd_01",rnd01);

   expression_t expression;
   expression.register_symbol_table(symbol_table);

   parser_t parser;
   parser.compile(monte_carlo_e_program,expression);

   const T approximate_e = expression.value();

   const T real_e = T(2.718281828459045235360287471352662); // or close enough...

   printf("e ~ %20.17f\terror: %20.17f\n",
          approximate_e,
          std::abs(real_e - approximate_e));
}

// Assembly:
subq $0xb68, %rsp            # imm = 0xB68
leaq 0xb47(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x111650
movq 0x28(%rsp), %rdx
leaq 0x330cf4(%rip), %rsi    # 0x449549
leaq 0xb48(%rsp), %rdi
callq 0x118770
jmp 0x118864
leaq 0xb47(%rsp), %rdi
callq 0x111790
leaq 0xb08(%rsp), %rdi
callq 0x118e20
jmp 0x118880
leaq 0xb00(%rsp), %rdi
movl $0x1, %esi
callq 0x118e70
jmp 0x118894
leaq 0xadf(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x111650
movq 0x20(%rsp), %rdx
leaq 0x330ec7(%rip), %rsi    # 0x449779
leaq 0xae0(%rsp), %rdi
callq 0x118770
jmp 0x1188c1
leaq 0xb00(%rsp), %rdi
leaq 0xae0(%rsp), %rsi
leaq 0xb08(%rsp), %rdx
callq 0x118eb0
jmp 0x1188e0
leaq 0xae0(%rsp), %rdi
callq 0x1117a8
leaq 0xadf(%rsp), %rdi
callq 0x111790
leaq 0xab8(%rsp), %rdi
callq 0x118f50
jmp 0x118909
leaq 0xab8(%rsp), %rdi
leaq 0xb00(%rsp), %rsi
callq 0x119000
jmp 0x118920
leaq 0x40(%rsp), %rdi
movl $0x7f, %esi
callq 0x1190b0
jmp 0x118931
leaq 0x190(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x1191e0
jmp 0x118945
leaq 0x40(%rsp), %rdi
callq 0x119a10
leaq 0x190(%rsp), %rdi
leaq 0xb48(%rsp), %rsi
leaq 0xab8(%rsp), %rdx
callq 0x119a80
jmp 0x11896e
leaq 0xab8(%rsp), %rdi
callq 0x11a310
movsd %xmm0, 0x18(%rsp)
jmp 0x118983
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movabsq $0x4005bf0a8b145769, %rax # imm = 0x4005BF0A8B145769
movq %rax, 0x30(%rsp)
movsd 0x38(%rsp), %xmm1
movsd %xmm1, 0x8(%rsp)
movsd 0x32b656(%rip), %xmm0   # 0x444008
subsd %xmm1, %xmm0
callq 0x11a330
movsd %xmm0, 0x10(%rsp)
jmp 0x1189c3
movsd 0x10(%rsp), %xmm1
movsd 0x8(%rsp), %xmm0
leaq 0x330daa(%rip), %rdi    # 0x449780
movb $0x2, %al
callq 0x111080
jmp 0x1189df
leaq 0x190(%rsp), %rdi
callq 0x11a350
leaq 0xab8(%rsp), %rdi
callq 0x11a550
leaq 0xb00(%rsp), %rdi
callq 0x11a590
leaq 0xb08(%rsp), %rdi
callq 0x11a610
leaq 0xb48(%rsp), %rdi
callq 0x1117a8
addq $0xb68, %rsp            # imm = 0xB68
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb38(%rsp)
movl %eax, 0xb34(%rsp)
leaq 0xb47(%rsp), %rdi
callq 0x111790
jmp 0x118b67
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb38(%rsp)
movl %eax, 0xb34(%rsp)
jmp 0x118b5a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb38(%rsp)
movl %eax, 0xb34(%rsp)
jmp 0x118b4d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb38(%rsp)
movl %eax, 0xb34(%rsp)
jmp 0x118ab7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb38(%rsp)
movl %eax, 0xb34(%rsp)
leaq 0xae0(%rsp), %rdi
callq 0x1117a8
leaq 0xadf(%rsp), %rdi
callq 0x111790
jmp 0x118b40
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb38(%rsp)
movl %eax, 0xb34(%rsp)
jmp 0x118b40
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb38(%rsp)
movl %eax, 0xb34(%rsp)
jmp 0x118b33
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb38(%rsp)
movl %eax, 0xb34(%rsp)
leaq 0x40(%rsp), %rdi
callq 0x119a10
jmp 0x118b33
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb38(%rsp)
movl %eax, 0xb34(%rsp)
leaq 0x190(%rsp), %rdi
callq 0x11a350
leaq 0xab8(%rsp), %rdi
callq 0x11a550
leaq 0xb00(%rsp), %rdi
callq 0x11a590
leaq 0xb08(%rsp), %rdi
callq 0x11a610
leaq 0xb48(%rsp), %rdi
callq 0x1117a8
movq 0xb38(%rsp), %rdi
callq 0x111440
nopw %cs:(%rax,%rax)
nop