Swift:执行中断,原因:EXC_BAD_INSTRUCTION错误
Swift: Execution was interrupted, reason: EXC_BAD_INSTRUCTION error
当我在 Playground 中尝试此操作时:
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 (code=EXC_I386_INVOP, subcode=0x0)
我似乎无法在我的代码中找到错误。我尝试了不同的输入值,但错误仍然存在。
如果你能看看我的代码并帮助我解决这个问题,那就太好了。感谢您的努力。
问题出在嵌套的 while
循环上。第一次循环时,n
设置为 9
,这意味着在最后一次通过嵌套循环时,您会得到 j == 9
,这显然意味着 j + 1 == 10
.但是您正在尝试获取不存在的 prices[j + 1] == prices[10]
。因此崩溃。
要查看此内容,请添加以下 if 语句:
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
循环代替。例如。第一个 while 可以替换为 for i in 0..<steps
而不会影响代码。这再次有助于减少可变状态和程序员错误。
我冒昧地重写了您的代码,使它更加 "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)
当我在 Playground 中尝试此操作时:
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 (code=EXC_I386_INVOP, subcode=0x0)
我似乎无法在我的代码中找到错误。我尝试了不同的输入值,但错误仍然存在。
如果你能看看我的代码并帮助我解决这个问题,那就太好了。感谢您的努力。
问题出在嵌套的 while
循环上。第一次循环时,n
设置为 9
,这意味着在最后一次通过嵌套循环时,您会得到 j == 9
,这显然意味着 j + 1 == 10
.但是您正在尝试获取不存在的 prices[j + 1] == prices[10]
。因此崩溃。
要查看此内容,请添加以下 if 语句:
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
循环代替。例如。第一个 while 可以替换为for i in 0..<steps
而不会影响代码。这再次有助于减少可变状态和程序员错误。
我冒昧地重写了您的代码,使它更加 "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)