Swift 中的二次公式
Quadratic Formula in Swift
我尝试为二次公式创建一个 x 值计算器。
代码:
var firstXValueVAR = 1.0
var secondXValueVAR = 1.0
var squaredValueVAR = 1.0
var firstOperationValueVAR = "+"
var secondOperationValueVAR = "+"
var constantValueVAR = 0.0
var topFormula = 0.0
var topFormula2 = 0.0
var bottomFormula = 0.0
var TotalSquaredValue = 0
var bSquared = 0
var totalX = 0.0
var totalX2 = 0.0
接下来,当我点击"Go"计算X时,我有这个,我不太确定我做错了什么,但是每次我打印X时,它都说nan,而且它还说对于 topFormula 和 topFormula2 (= nan)。
func updateValues(){
var secondXValueInt = Int(secondXValueVAR)
var firstXValueInt = Int(firstXValueVAR)
var squaredValueInt = Int(squaredValueVAR)
var constantValueInt = Int(constantValueVAR)
bSquared = secondXValueInt << 2
TotalSquaredValue = firstXValueInt << squaredValueInt
firstXValueVAR = Double(firstXValue.text!)!
secondXValueVAR = Double(secondXValue.text!)!
squaredValueVAR = Double(squaredValue.text!)!
constantValueVAR = Double(constantValue.text!)!
if operations.contains(firstOperationValue.text!){
firstOperationValueVAR = firstOperationValue.text!
if secondOperationValueVAR == "*"{
topFormula = -(secondXValueVAR) + sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX = topFormula / bottomFormula
print(squaredValue)
topFormula2 = -(secondXValueVAR) - sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX2 = topFormula2 / bottomFormula
print(topFormula)
print(topFormula2)
print(bottomFormula)
print("X = \(totalX) & \(totalX2)")
}
if secondOperationValueVAR == "/"{
topFormula = -(secondXValueVAR) + sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX = topFormula / bottomFormula
print(squaredValue)
topFormula2 = -(secondXValueVAR) - sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX2 = topFormula2 / bottomFormula
print(topFormula)
print(topFormula2)
print(bottomFormula)
print("X = \(totalX) & \(totalX2)")
}
if secondOperationValueVAR == "+"{
topFormula = -(secondXValueVAR) + sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX = topFormula / bottomFormula
print(squaredValue)
topFormula2 = -(secondXValueVAR) - sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX2 = topFormula2 / bottomFormula
print(topFormula)
print(topFormula2)
print(bottomFormula)
print("X = \(totalX) & \(totalX2)")
}
if secondOperationValueVAR == "-"{
topFormula = -(secondXValueVAR) + sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX = topFormula / bottomFormula
print(squaredValue)
topFormula2 = -(secondXValueVAR) - sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX2 = topFormula2 / bottomFormula
print(topFormula)
print(topFormula2)
print(bottomFormula)
print("X = \(totalX) & \(totalX2)")
}
}
if operations.contains(secondOperationValue.text!){
secondOperationValueVAR = secondOperationValue.text!
}
}
@IBAction func GoAction(sender: AnyObject) {
updateValues()
}
关键问题是您使用的是sqrt
,它不能处理负数,因为结果是虚数。所以,它表明它是 "not a number" (nan
)。例如,3 - sqrt(4)
是 1
,但 3 - sqrt(-4)
实际上是 3 - 2i
。但是 sqrt
函数不能为你做这件事,所以你要么必须使用处理虚数的库,要么自己手动处理。
几个与 nan
错误无关的问题:
您正在根据 firstXValueVAR
的内容设置 firstXValueInt
(以及其他类似的 Int
变量),但是在您这样做之后,您从 UITextField
重新检索 firstXValueVAR
。这似乎倒退了。首先从文本字段中获取值,然后开始计算。
您正在将文本字段值转换为 Double
,然后将其转换为 Int
,以便您可以使用移位运算符对其进行平方。当然,如果您确信这些值永远不会包含非整数值,您就可以这样做,但这是一个巨大的限制,只是为了让您可以享受按位移位操作的效率。另外,按位运算并没有按照我认为的那样进行。 << 2
相当于乘以四,而不是平方。
如果您真的那么关心效率,我不会多次重新计算判别式。就个人而言,我建议丢失此整数转换并避免一整类可能出现的问题。
我不明白为什么您似乎要根据 [=29] 的值重复计算 totalX
和 totalX2
的代码四次=].如果你打算这样做,我要么转向 if
-else if
模式(或者,更好的是 switch
语句)然后有一个 default
子句来检测是否找到了四个预期值中的 none 个。
无论如何,如果我想要这个二次公式的根,我会这样做:
let a = Double(firstXValue.text!)!
let b = Double(secondXValue.text!)!
let c = Double(constantValue.text!)!
let bSquared = b * b
let discriminant = bSquared - (4 * a * c)
let isImaginary = discriminant < 0
let discrimimantAbsSqrt = sqrt(fabs(discriminant))
if isImaginary {
print("X = (\(-b) + \(discrimimantAbsSqrt)i)/\(2*a) & (\(-b) - \(discrimimantAbsSqrt)i)/\(2*a)")
} else {
let topFormula = -b + discrimimantAbsSqrt
let bottomFormula = 2 * a
let totalX = topFormula / bottomFormula
let topFormula2 = -b - discrimimantAbsSqrt
let totalX2 = topFormula2 / bottomFormula
print("X = \(totalX) & \(totalX2)")
}
请注意,上面的代码取消了所有这些属性并仅使用局部变量(UITextField
控件除外)。您可以通过确保仅在真正需要的地方使用属性来最大程度地减少意外后果,并且我个人会将所有计算保留为局部变量。就个人而言,我也会避免使用强制解包(!
)并进行条件绑定以优雅地处理 nil
值,但这取决于你。
我尝试为二次公式创建一个 x 值计算器。
代码:
var firstXValueVAR = 1.0
var secondXValueVAR = 1.0
var squaredValueVAR = 1.0
var firstOperationValueVAR = "+"
var secondOperationValueVAR = "+"
var constantValueVAR = 0.0
var topFormula = 0.0
var topFormula2 = 0.0
var bottomFormula = 0.0
var TotalSquaredValue = 0
var bSquared = 0
var totalX = 0.0
var totalX2 = 0.0
接下来,当我点击"Go"计算X时,我有这个,我不太确定我做错了什么,但是每次我打印X时,它都说nan,而且它还说对于 topFormula 和 topFormula2 (= nan)。
func updateValues(){
var secondXValueInt = Int(secondXValueVAR)
var firstXValueInt = Int(firstXValueVAR)
var squaredValueInt = Int(squaredValueVAR)
var constantValueInt = Int(constantValueVAR)
bSquared = secondXValueInt << 2
TotalSquaredValue = firstXValueInt << squaredValueInt
firstXValueVAR = Double(firstXValue.text!)!
secondXValueVAR = Double(secondXValue.text!)!
squaredValueVAR = Double(squaredValue.text!)!
constantValueVAR = Double(constantValue.text!)!
if operations.contains(firstOperationValue.text!){
firstOperationValueVAR = firstOperationValue.text!
if secondOperationValueVAR == "*"{
topFormula = -(secondXValueVAR) + sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX = topFormula / bottomFormula
print(squaredValue)
topFormula2 = -(secondXValueVAR) - sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX2 = topFormula2 / bottomFormula
print(topFormula)
print(topFormula2)
print(bottomFormula)
print("X = \(totalX) & \(totalX2)")
}
if secondOperationValueVAR == "/"{
topFormula = -(secondXValueVAR) + sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX = topFormula / bottomFormula
print(squaredValue)
topFormula2 = -(secondXValueVAR) - sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX2 = topFormula2 / bottomFormula
print(topFormula)
print(topFormula2)
print(bottomFormula)
print("X = \(totalX) & \(totalX2)")
}
if secondOperationValueVAR == "+"{
topFormula = -(secondXValueVAR) + sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX = topFormula / bottomFormula
print(squaredValue)
topFormula2 = -(secondXValueVAR) - sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX2 = topFormula2 / bottomFormula
print(topFormula)
print(topFormula2)
print(bottomFormula)
print("X = \(totalX) & \(totalX2)")
}
if secondOperationValueVAR == "-"{
topFormula = -(secondXValueVAR) + sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX = topFormula / bottomFormula
print(squaredValue)
topFormula2 = -(secondXValueVAR) - sqrt(Double(bSquared) - (4 * firstXValueVAR * constantValueVAR))
bottomFormula = 2 * firstXValueVAR
totalX2 = topFormula2 / bottomFormula
print(topFormula)
print(topFormula2)
print(bottomFormula)
print("X = \(totalX) & \(totalX2)")
}
}
if operations.contains(secondOperationValue.text!){
secondOperationValueVAR = secondOperationValue.text!
}
}
@IBAction func GoAction(sender: AnyObject) {
updateValues()
}
关键问题是您使用的是sqrt
,它不能处理负数,因为结果是虚数。所以,它表明它是 "not a number" (nan
)。例如,3 - sqrt(4)
是 1
,但 3 - sqrt(-4)
实际上是 3 - 2i
。但是 sqrt
函数不能为你做这件事,所以你要么必须使用处理虚数的库,要么自己手动处理。
几个与 nan
错误无关的问题:
您正在根据
firstXValueVAR
的内容设置firstXValueInt
(以及其他类似的Int
变量),但是在您这样做之后,您从UITextField
重新检索firstXValueVAR
。这似乎倒退了。首先从文本字段中获取值,然后开始计算。您正在将文本字段值转换为
Double
,然后将其转换为Int
,以便您可以使用移位运算符对其进行平方。当然,如果您确信这些值永远不会包含非整数值,您就可以这样做,但这是一个巨大的限制,只是为了让您可以享受按位移位操作的效率。另外,按位运算并没有按照我认为的那样进行。<< 2
相当于乘以四,而不是平方。如果您真的那么关心效率,我不会多次重新计算判别式。就个人而言,我建议丢失此整数转换并避免一整类可能出现的问题。
我不明白为什么您似乎要根据 [=29] 的值重复计算
totalX
和totalX2
的代码四次=].如果你打算这样做,我要么转向if
-else if
模式(或者,更好的是switch
语句)然后有一个default
子句来检测是否找到了四个预期值中的 none 个。
无论如何,如果我想要这个二次公式的根,我会这样做:
let a = Double(firstXValue.text!)!
let b = Double(secondXValue.text!)!
let c = Double(constantValue.text!)!
let bSquared = b * b
let discriminant = bSquared - (4 * a * c)
let isImaginary = discriminant < 0
let discrimimantAbsSqrt = sqrt(fabs(discriminant))
if isImaginary {
print("X = (\(-b) + \(discrimimantAbsSqrt)i)/\(2*a) & (\(-b) - \(discrimimantAbsSqrt)i)/\(2*a)")
} else {
let topFormula = -b + discrimimantAbsSqrt
let bottomFormula = 2 * a
let totalX = topFormula / bottomFormula
let topFormula2 = -b - discrimimantAbsSqrt
let totalX2 = topFormula2 / bottomFormula
print("X = \(totalX) & \(totalX2)")
}
请注意,上面的代码取消了所有这些属性并仅使用局部变量(UITextField
控件除外)。您可以通过确保仅在真正需要的地方使用属性来最大程度地减少意外后果,并且我个人会将所有计算保留为局部变量。就个人而言,我也会避免使用强制解包(!
)并进行条件绑定以优雅地处理 nil
值,但这取决于你。