C#-索引超出范围 [英] C# - Index was out of range

查看:183
本文介绍了C#-索引超出范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将C ++类转换为C#,并在此过程中学习C ++的知识.我以前从未遇到过vector<>,而我的理解是,这就像C#中的List<>函数一样.在类转换期间,我使用List futures_price = New List(Convert.ToInt32(no_steps)+ 1);重新编写了代码.一旦运行代码,就会出现索引超出范围"错误.

I am trying to convert a C++ class to C# and in the process learn something of C++. I had never run into a vector<> before and my understanding is this is like a List<> function in C#. During the conversion of the class I re-wrote the code using List futures_price = New List(Convert.ToInt32(no_steps) + 1);. As soon as I run the code, I get a "Index was out of range" error.

环顾了SOF,我相信问题在于与此相关的参数不在索引范围内,但是我看不到使用以下代码来解决此问题的简单解决方案.

Having looked around on SOF, I believe the issue is regarding the parameter being out of index range relating to this, but I do not see a simple solution to solve this with the below code.

尤其是,这是引发错误的行:futures_prices [0] = spot_price * Math.Pow(d,no_steps);

In particular, this is the line that is triggering the error: futures_prices[0] = spot_price * Math.Pow(d, no_steps);

下面是完整的代码:

public double futures_option_price_call_american_binomial(double spot_price, double option_strike, double r, double sigma, double time, double no_steps)
        {

           //double spot_price, // price futures contract
           //double option_strike, // exercise price
           //double r, // interest rate
           //double sigma, // volatility
           //double time, // time to maturity
           //int no_steps

            List<double> futures_prices = new List<double>(Convert.ToInt32(no_steps) + 1);
               //(no_steps+1);
           //double call_values = (no_steps+1);
            List<double> call_values = new List<double>(Convert.ToInt32(no_steps) + 1);

           double t_delta = time/no_steps;
           double Rinv = Math.Exp(-r*(t_delta));
           double u = Math.Exp(sigma * Math.Sqrt(t_delta));
           double d = 1.0/u;
           double uu= u*u;
           double pUp   = (1-d)/(u-d);   // note how probability is calculated
           double pDown = 1.0 - pUp;

           futures_prices[0] = spot_price * Math.Pow(d, no_steps);

            int i;

            for (i=1; i<=no_steps; ++i) futures_prices[i] = uu*futures_prices[i-1]; // terminal tree nodes
            for (i=0; i<=no_steps; ++i) call_values[i] = Math.Max(0.0, (futures_prices[i]-option_strike));
            for (int step = Convert.ToInt32(no_steps) - 1; step >= 0; --step)
            {
                for (i = 0; i <= step; ++i)
                {
                    futures_prices[i] = d * futures_prices[i + 1];
                    call_values[i] = (pDown * call_values[i] + pUp * call_values[i + 1]) * Rinv;
                    call_values[i] = Math.Max(call_values[i], futures_prices[i] - option_strike); // check for exercise
                };
            };

            return call_values[0];
        }

这是C ++的原始来源:

Here is the original source in C++:

double futures_option_price_call_american_binomial(const double& F, // price futures contract
                           const double& K, // exercise price
                           const double& r, // interest rate
                           const double& sigma, // volatility
                           const double& time, // time to maturity
                           const int& no_steps) { // number of steps
   vector<double> futures_prices(no_steps+1);
   vector<double> call_values (no_steps+1);
   double t_delta= time/no_steps;
   double Rinv = exp(-r*(t_delta));
   double u = exp(sigma*sqrt(t_delta));
   double d = 1.0/u;
   double uu= u*u;
   double pUp   = (1-d)/(u-d);   // note how probability is calculated
   double pDown = 1.0 - pUp;
   futures_prices[0] = F*pow(d, no_steps);
   int i;
   for (i=1; i<=no_steps; ++i) futures_prices[i] = uu*futures_prices[i-1]; // terminal tree nodes
   for (i=0; i<=no_steps; ++i) call_values[i] = max(0.0, (futures_prices[i]-K));
   for (int step=no_steps-1; step>=0; --step) {
      for (i=0; i<=step; ++i)   {
     futures_prices[i] = d*futures_prices[i+1];
     call_values[i] = (pDown*call_values[i]+pUp*call_values[i+1])*Rinv;
     call_values[i] = max(call_values[i], futures_prices[i]-K); // check for exercise
      };
   };
   return call_values[0];
};

推荐答案

正如SLaks所说,在这种情况下最好使用Array. C#列表中填充有Add方法,而值则通过Remove方法删除...这将更加复杂,并且内存/性能也很昂贵,因为您还要替换值.

As SLaks says, it's better to use an Array in this situation. C# lists are filled with Add method and values are removed through Remove method... this would be more complicated and memory/performance expensive as you are also replacing values.

public Double FuturesOptionPriceCallAmericanBinomial(Double spotPrice, Double optionStrike, Double r, Double sigma, Double time, Double steps)
{
    // Avoid calling Convert multiple times as it can be quite performance expensive.
    Int32 stepsInteger = Convert.ToInt32(steps);

    Double[] futurePrices = new Double[(stepsInteger + 1)];
    Double[] callValues = new Double[(stepsInteger + 1)];

    Double tDelta = time / steps;
    Double rInv = Math.Exp(-r * (tDelta));
    Double u = Math.Exp(sigma * Math.Sqrt(tDelta));
    Double d = 1.0 / u;
    Double uu = u * u;
    Double pUp = (1 - d) / (u - d);
    Double pDown = 1.0 - pUp;

    futurePrices[0] = spotPrice * Math.Pow(d, steps);

    for (Int32 i = 1; i <= steps; ++i)
        futurePrices[i] = uu * futurePrices[(i - 1)];

    for (Int32 i = 0; i <= steps; ++i)
        callValues[i] = Math.Max(0.0, (futurePrices[i] - optionStrike));

    for (Int32 step = stepsInteger - 1; step >= 0; --step)
    {
        for (Int32 i = 0; i <= step; ++i)
        {
            futurePrices[i] = d * futurePrices[(i + 1)];
            callValues[i] = ((pDown * callValues[i]) + (pUp * callValues[i + 1])) * rInv;
            callValues[i] = Math.Max(callValues[i], (futurePrices[i] - option_strike));
        }
    }

    return callValues[0];
}

这篇关于C#-索引超出范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆