【问题标题】:Swift: Execution was interrupted, reason: EXC_BAD_INSTRUCTION errorSwift:执行被中断,原因:EXC_BAD_INSTRUCTION 错误
【发布时间】:2017-02-25 13:15:48
【问题描述】:

当我在 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)

我似乎无法在我的代码中找到错误。我尝试了不同的输入值,但错误仍然存​​在。

如果您可以查看我的代码并帮助我解决此问题,那就太好了。感谢您的努力。

【问题讨论】:

    标签: arrays swift loops swift2 exc-bad-instruction


    【解决方案1】:

    问题在于嵌套的 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..&lt;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)
    

    【讨论】:

    • 感谢先生花时间浏览我的代码。这是有道理的
    • ...您提供给我的解释绝对有道理。是的,我现在可以看到为什么会发生错误。不幸的是,结果没有多大意义。我将通过我的代码。也许我在公式中犯了错误或错误地执行了它。我也感谢您的建议(因为我是 Swift 的新手)。亲切的问候。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 2020-01-13
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多