Division by a square

Hello,

In the following function (in the class Option_Price_Family), I compute several quantities which are all of type double. At the end, I divide the double "rmp_phi*tmp_one - tmp_phi*rmp_one" by the double "tmp_one * tmp_one", or "pow(tmp_one,2)". When I compute ""rmp_phi*tmp_one - tmp_phi*rmp_one/ tmp_one", which approximately -0.075/0.56, I obtain the right result. But when I divide by the square, or when I divide the previous result again by "tmp_one", I obtain crazy results, even positive ones (while I divide a negative double by a positive double).

I don't think it could be a type problem since I tried to cast everything with double. It is not a division by 0 since I can compute the denominator which is approximately 0.32...

Would anyone have any idea?
Many thanks


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

double Option_Price_Family::compute_delta_before_expectation(const double current_underlying_value, const double s, const double t, const double sigma_s_t,const Option_Price_Family& next_option_price_family) {
    Price_and_Trajectory pat;
    double result;
    double tmp ;
    double tmp_phi = 0.;
    double tmp_one = 0.;
    double rmp ;
    double rmp_phi = 0.;
    double rmp_one = 0.;
    double diff_x_alpha = 0.;
    double indicatrice = 0.;
    double price = 0.;
    
    /// keep track of recomputations when result_one ~ 0
    if (S_use_localization) {
        for (int j=0; j<Option_Price_Family::S_SIMUL__M; j++) {
            pat = next_option_price_family.m_prices_and_trajectories[j];
            diff_x_alpha = pat.m_last_underlying_value - current_underlying_value;
            
            tmp = ( t * pat.m_last_brownian - s * pat.m_current_brownian + sigma_s_t ) / (pat.m_last_underlying_value* sigma_s_t);
            if (S_use_reverse_formula) {
                tmp *= S_F(- diff_x_alpha)- S_H(- diff_x_alpha);
                tmp += S_f(- diff_x_alpha);
            } else {
                tmp *= S_H(diff_x_alpha)- S_F(diff_x_alpha);
                tmp += S_f(diff_x_alpha);
            }
            tmp_one += tmp;
            tmp_phi += tmp * pat.m_option_price;
            
            //rmp = ( pow( t * pat.m_last_brownian - s * pat.m_current_brownian + sigma_s_t, 2 ) +t * pat.m_last_brownian - s * pat.m_current_brownian + sigma_s_t - s*t*(t-s) )/ (pow(pat.m_last_underlying_value,2)* sigma_s_t);
            
            rmp = ( pow( t * pat.m_last_brownian - s * pat.m_current_brownian + sigma_s_t, 2 ) +(t * pat.m_last_brownian - s * pat.m_current_brownian + sigma_s_t)*sigma_s_t - s*t*(t-s) )/ (pow(pat.m_last_underlying_value,2)* pow(sigma_s_t,2));
            if (S_use_reverse_formula) {
                rmp *= (S_F( diff_x_alpha)- S_H( diff_x_alpha));
                rmp -= (S_f( diff_x_alpha)*( t * pat.m_last_brownian - s * pat.m_current_brownian + sigma_s_t ) / pat.m_last_underlying_value);
            } else {
                rmp *= S_H(diff_x_alpha) - S_F(diff_x_alpha);
                rmp -= S_f(diff_x_alpha)*( t * pat.m_last_brownian - s * pat.m_current_brownian + sigma_s_t ) / (pat.m_last_underlying_value*sigma_s_t);
            }
            rmp_one += rmp;
            rmp_phi += rmp * pat.m_option_price;
        }
    } else {
        for (int j=0; j<Option_Price_Family::S_SIMUL__M; j++) {
            pat = next_option_price_family.m_prices_and_trajectories[j];
            tmp = ( t * pat.m_last_brownian - s * pat.m_current_brownian + sigma_s_t ) / pat.m_last_underlying_value;
            diff_x_alpha = pat.m_last_underlying_value - current_underlying_value;
            if (S_use_reverse_formula) {
                tmp *= - S_H(- diff_x_alpha);
            } else {
                tmp *= S_H(diff_x_alpha);
            }
            tmp_one += tmp;
            tmp_phi += tmp * pat.m_option_price;
        }
    }
    tmp_one /= Option_Price_Family::S_SIMUL__M;
    tmp_phi /= Option_Price_Family::S_SIMUL__M;
    rmp_one /= Option_Price_Family::S_SIMUL__M;
    rmp_phi /= Option_Price_Family::S_SIMUL__M;
    
    price = std::max(S_payoff(current_underlying_value),S_one_step_discount*tmp_phi/tmp_one);
    indicatrice = (price<S_payoff(current_underlying_value))?1:0;
    
    //return S_one_step_discount*(tmp_phi*rmp_one - rmp_phi*tmp_one)/(pow(rmp_one,2));
    //return S_one_step_discount*(rmp_phi*tmp_one - tmp_phi*rmp_one)/(pow(tmp_one,2));
    //return  ( pow( t * pat.m_last_brownian - s * pat.m_current_brownian + sigma_s_t, 2 ) +(t * pat.m_last_brownian - s * pat.m_current_brownian + sigma_s_t)*sigma_s_t - s*t*(t-s) )/ (pow(pat.m_last_underlying_value,2)* sigma_s_t);
    
    //double square = tmp_one*tmp_one;
    result = (double)(rmp_phi*tmp_one - tmp_phi*rmp_one)/((double)tmp_one * (double)tmp_one);
    //return result/tmp_one;
    //return (tmp_one/pow(tmp_one,2));
    return result;
}
Topic archived. No new replies allowed.