2016-10-16 5 views
0

При попытке это площадка:Swift: выполнение было прервано, причина: EXC_BAD_INSTRUCTION ошибка

func StockEvolution(S_0:Double, _ down:Double, _ up:Double, _ totalsteps:Int, _ upsteps:Int) -> Double // function being used in calcCall() 
{ 
    var S_t:Double = S_0 * pow(up, Double(upsteps)) * pow(down, Double(totalsteps - upsteps)) 
    return S_t 
} 

func CallPayoff(S:Double, _ K:Double) -> Double // function being used in calcCall() 
{ 
    return max(S - K, 0.0) 
} 

func calcCall(S_0:Double, _ down:Double, _ up:Double, _ r:Double, _ steps:Int, _ K:Double) -> Double //calculate Call-Option 
{ 
    var prices = [Double]() 
    var q = 0.6 //risk-neutral probability factor 

var i = 0 
while i < steps 
{ 
    var payOff = CallPayoff(StockEvolution(S_0, down, up, steps, i), K) 
    prices.append(payOff) 
    i += 1 
} 

var n = steps - 1 
while n >= 0 
{ 
    var j = 0 
    while j <= n 
    { 
     var value = (1/r) * (prices[j + 1] * q + (1 - q) * prices[j]) 
     prices.removeAtIndex(j) 
     prices.insert(value, atIndex: j) 
     j += 1 
    } 
    n -= 1 
} 
return prices[0] 
} 

Делая это:

var checkPrice = calcCall(100, 0.6, 1.5, 1.05, 10, 200) 

Это дает мне эту ошибку:

казни прерывание, причина: EXC_BAD_INSTRUCTION (код = EXC_I386_INVOP, подкод = 0x0)

I ca похоже, не обнаружил ошибку в моем коде. Я пробовал с разными входными значениями, но ошибка все еще происходит.

Было бы здорово, если бы вы могли взглянуть на мой код и помочь мне исправить эту проблему. Спасибо за ваши старания.

ответ

0

Проблема с вашими вложенными петлями while. При первом прохождении цикла n устанавливается в 9, что означает, что на заключительном проходе через вложенный цикл вы получаете j == 9, что явно означает j + 1 == 10. Но вы пытаетесь получить prices[j + 1] == prices[10], которого не существует. Отсюда крушение.

Чтобы увидеть это, добавьте следующее, если заявление:

if j + 1 < prices.count { 
    let value = (1/r) * (prices[j + 1] * q + (1 - q) * prices[j]) 
    prices.removeAtIndex(j) 
    prices.insert(value, atIndex: j) 
} 
j += 1 

Вы больше не будете получать плохую ошибку доступа.

Теперь я не знаю проблемную область, поэтому не могу сказать , почему ваш алгоритм был некорректен. Таким образом, ответ, который я предоставил, может не дать вам ожидаемых значений. Вам, вероятно, придется разобраться, почему вы пытаетесь получить доступ к несуществующему индексу и как обойти это.

Наконец, если я могу, некоторые моменты вообще стиль:

  • Вы могли бы заметили, что я сменил var в примере кода выше для let. Поскольку value никогда не мутируется (вместо этого переопределяется при каждом проходе через цикл), его не нужно изменять. Удаление измененного состояния облегчит поиск проблем в вашем коде.
  • Вы использовали много циклов while с изменяемым состоянием, чтобы отслеживать прогресс через них. Все они могут быть заменены петлями for...in. Например. первый может быть заменен на for i in 0..<steps без какого-либо влияния на код. Это опять-таки помогает сократить на mutable состояние и ошибку программиста.

Я взял на себя смелость переписать свой код, чтобы сделать его немного более «Swifty», а также удалив как можно больше изменяемого состояния. Вот он:

func stockEvolution(s_0: Double, _ down: Double, _ up: Double, _ totalsteps: Int, _ upsteps: Int) -> Double { 
    let s_t: Double = s_0 * pow(up, Double(upsteps)) * pow(down, Double(totalsteps - upsteps)) 
    return s_t 
} 

func callPayoff(s: Double, _ k: Double) -> Double { 
    return max(s - k, 0.0) 
} 

func calcCall(s_0: Double, _ down: Double, _ up: Double, _ r: Double, _ steps:Int, _ k: Double) -> Double { 
    var prices = Array(0..<steps).map { step in 
     return callPayoff(stockEvolution(s_0, down, up, steps, step), k) 
    } 
    let q = 0.6 //risk-neutral probability factor 

    for n in (0..<steps).reverse() { 
     for j in 0...n where j + 1 < prices.count { 
      let value = (1/r) * (prices[j + 1] * q + (1 - q) * prices[j]) 
      prices.removeAtIndex(j) 
      prices.insert(value, atIndex: j) 
     } 
    } 
    return prices[0] 
} 

let checkPrice = calcCall(100, 0.6, 1.5, 1.05, 10, 200) 
+0

Благодарю вас, сэр, за то, что вы нашли время, чтобы просмотреть мой код. Это имеет смысл – heisenberg

+0

... Объяснение, которое вы мне предоставили, имеет смысл. Да, теперь я вижу, почему возникает ошибка. К сожалению, результат не имеет большого смысла. Я просмотрю свой код. Возможно, я допустил ошибку в формуле или неправильно ее осуществил. Я также ценю ваши советы (потому что я новичок в Swift). С уважением. – heisenberg