// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbx
subq $0xaf0, %rsp            # imm = 0xAF0
leaq 0x12addf(%rip), %rsi    # 0x23b111
leaq 0x30(%rsp), %rdi
leaq 0x1c8(%rsp), %rdx
callq 0x1102e8
leaq 0x50(%rsp), %rdi
callq 0x110566
leaq 0x8(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x110596
leaq 0x12afdf(%rip), %rsi    # 0x23b341
leaq 0x1c8(%rsp), %rdi
leaq 0x78(%rsp), %rdx
callq 0x1102e8
leaq 0x8(%rsp), %rdi
leaq 0x1c8(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0x1105ba
leaq 0x1c8(%rsp), %rdi
callq 0x10e5e8
leaq 0x10(%rsp), %rdi
callq 0x11061a
leaq 0x10(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x11067a
leaq 0x78(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x1106d6
leaq 0x1c8(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x1107e6
leaq 0x78(%rsp), %rdi
callq 0x110dfe
leaq 0x1c8(%rsp), %rdi
leaq 0x30(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0x110e46
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
movsd 0x125c00(%rip), %xmm1   # 0x236008
subsd %xmm0, %xmm1
andpd 0x125ccc(%rip), %xmm1   # 0x2360e0
leaq 0x12af2d(%rip), %rdi    # 0x23b348
movb $0x2, %al
callq 0x10e060
leaq 0x1c8(%rsp), %rdi
callq 0x1112c8
leaq 0x10(%rsp), %rdi
callq 0x111402
leaq 0x8(%rsp), %rdi
callq 0x111418
leaq 0x30(%rsp), %rdi
callq 0x10e5e8
addq $0xaf0, %rsp            # imm = 0xAF0
popq %rbx
retq
jmp 0x110458
movq %rax, %rbx
leaq 0x1c8(%rsp), %rdi
callq 0x1112c8
jmp 0x11047e
movq %rax, %rbx
leaq 0x78(%rsp), %rdi
callq 0x110dfe
jmp 0x11047e
jmp 0x11047b
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x111402
jmp 0x1104a1
jmp 0x11049e
movq %rax, %rbx
leaq 0x1c8(%rsp), %rdi
callq 0x10e5e8
jmp 0x1104a1
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x111418
jmp 0x1104b2
jmp 0x1104af
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x10e5e8
movq %rbx, %rdi
callq 0x10e310