尝试在 Swift Playground 中打印函数时出现 EXC_BAD_INSTRUCTION 错误

Posted

技术标签:

【中文标题】尝试在 Swift Playground 中打印函数时出现 EXC_BAD_INSTRUCTION 错误【英文标题】:EXC_BAD_INSTRUCTION error when attempting to print a function in Swift Playground 【发布时间】:2016-11-16 16:53:18 【问题描述】:

我目前正在处理一个大学数学项目,该项目要求我创建一个与抵押贷款相关的应用程序。我正在尝试编写 Swift 代码来计算每个月支付的抵押贷款的本金和利息。

我写的代码如下(值得一提的是我对编码很陌生,对Python有一点经验,这都是自学的,欢迎批评!):

// Declare all variables
// y = periodic interest rate
// n = time left of repayment period (months)

let y = [Float](arrayLiteral: 0.02/12,0.03/12,0.04/12,0.05/12)
let n = [Float](arrayLiteral: 240,180,120,60)

var x = [Float]()
var interest = [Float]()
var T_1 = [Int]()

// Create Array from 0 to 240
for a in 0...240 
    T_1.append(a)


// Create Array of all 240 interest values

for a in 0...239 
    if a < 60 
        interest.append(y[0])
        var repay = n[0]
        x.append(repay)
    
    else if a < 120 
        interest.append(y[1])
        var repay = n[1]
        x.append(repay)
    
    else if a < 180 
        interest.append(y[2])
        var repay = n[2]
        x.append(repay)
    
    else 
        interest.append(y[3])
        var repay = n[3]
        x.append(repay)
    

print("Interest array:",interest)

// Calculate Each months Principal paid and Interest Paid

func variablerate(P: inout Float) -> [Float] 
    var principal = [Float]()
    var i_paid = [Float]()
    var repayments = [Float]()
    var R = Float(0)
    let temporaryP = P
    i_paid.append(0)

    for a in 0...240 
        if (a>0) && (a<240) && (interest[a-1] == interest[a]) 
            let ip = P*(1+interest[a-1])-P
            i_paid.append(i_paid[a-1] + ip)
            P = (1+interest[a-1])*temporaryP
            P = P-R
            let h = interest[a]
            R = (P*h)/(1-pow(1+h,Float(interest.count-a)))
            repayments.append(R)
            principal.append(round(100*P)/100)
        
        else if a==240 || a==241 
            P = P - R
            principal.append(round(100*P)/100)
            let ip = P*(1+interest[a-1])-P
            i_paid.append(i_paid[a-1] + ip)
            let h = interest[a-1]
            P = P*(1+h)
        
        else 
            P = P - R
            let h = interest[a]
            R = (P*h)/(1-pow(1+h,Float(interest.count-a)))
            repayments.append(R)
            principal.append(round(100*P)/100)
            let ip = P*(1+interest[a])-P
            i_paid.append(i_paid[a-1] + ip)
            P = P*(1+h)
        
    
    return i_paid
    return principal


var z = Float(100000)

print(variablerate(P: &z)) //This is where the error appears

给出的错误是:

错误:执行被中断,原因:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP,subcode=0x0)。

非常感谢您对此问题的任何帮助或指导!

【问题讨论】:

在此之前我遇到了错误,例如未解析的标识符“pow”? @dylan 我的 Swift Playground 上没有出现其他错误。 pow(double, double) 已用于使用幂的表达式。 a 为零时,在已编译的项目中运行代码会在i_paid.append(i_paid[a-1] + ip) 处出现“致命错误:索引超出范围”而中止... 请注意,return principal 永远不会被执行。 【参考方案1】:

崩溃的原因是索引超出范围

你得到 Index out of range 异常,因为在代码中你正在运行一个从 0 到 240 的循环,并且从局部变量 a 减去 1 所以在第一次迭代 a将包含 0,从 0 中减去 1 将给出负索引。

这里是错误

对于 0...240 if (a>0) && (ainterest[a-1] ==interest[a])

以下代码已修正

// Declare all variables
// y = periodic interest rate
// n = time left of repayment period (months)

let y = [Float](arrayLiteral: 0.02/12,0.03/12,0.04/12,0.05/12)
let n = [Float](arrayLiteral: 240,180,120,60)

var x = [Float]()
var interest = [Float]()
var T_1 = [Int]()

// Create Array from 0 to 240
for a in 0...240 
    T_1.append(a)


// Create Array of all 240 interest values

for a in 0...239 
    if a < 60 
        interest.append(y[0])
        var repay = n[0]
        x.append(repay)
    
    else if a < 120 
        interest.append(y[1])
        var repay = n[1]
        x.append(repay)
    
    else if a < 180 
        interest.append(y[2])
        var repay = n[2]
        x.append(repay)
    
    else 
        interest.append(y[3])
        var repay = n[3]
        x.append(repay)
    

print("Interest array:",interest)

// Calculate Each months Principal paid and Interest Paid

func variablerate(P: inout Float) -> [Float] 
    var principal = [Float]()
    var i_paid = [Float]()
    var repayments = [Float]()
    var R = Float(0)
    let temporaryP = P
    i_paid.append(0)

    for a in 1...240  // Code corrected now loop go from 1 to 240 
        if (a>0) && (a<240) && (interest[a-1] == interest[a]) 
            let ip = P*(1+interest[a-1])-P
            i_paid.append(i_paid[a-1] + ip)
            P = (1+interest[a-1])*temporaryP
            P = P-R
            let h = interest[a]
            R = (P*h)/(1-pow(1+h,Float(interest.count-a)))
            repayments.append(R)
            principal.append(round(100*P)/100)
        
        else if a == 240 || a == 241 
            P = P - R
            principal.append(round(100*P)/100)
            let ip = P*(1+interest[a-1])-P
            i_paid.append(i_paid[a-1] + ip)
            let h = interest[a-1]
            P = P*(1+h)
        
        else 
            P = P - R
            let h = interest[a]
            R = (P*h)/(1-pow(1+h,Float(interest.count-a)))
            repayments.append(R)
            principal.append(round(100*P)/100)
            let ip = P*(1+interest[a])-P
            i_paid.append(i_paid[a-1] + ip)
            P = P*(1+h)
        
    
    //return i_paid
    return principal


var z = Float(100000)

print("\(variablerate(P: &z))")

【讨论】:

以上是关于尝试在 Swift Playground 中打印函数时出现 EXC_BAD_INSTRUCTION 错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 Swift Playground 打印和循环两次?

如何使用 Swift Playground 打印到控制台?

Swift 3 Playground 以本地格式记录日期。如何?

Swift Playground 显示错误的语句执行次数(数组上的 forEach)

如何使用 Swift 在 Playground 中获取用户交互事件

在 xCode Playground 上打印 /n [重复]