2016-02-14 1 views
0

J'ai essayé de créer une calculatrice de valeur x pour la formule quadratique.Formule quadratique dans Swift

code:

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 

Ensuite, lorsque je clique sur « Go » pour calculer X, j'ai, et je ne suis pas vraiment sûr de ce que je fait de mal, mais chaque fois que j'imprime X, il dit nan, et il dit aussi que pour topFormula et 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() 
} 
+0

question générale: avez-vous vérifié ce qui se passe dans l'utilisateur entre le texte dans vos champs de texte? – luk2302

+0

Avez-vous essayé un point d'arrêt et vérifié étape par étape le code? – UlyssesR

+0

Salut Andy. Il y a une très bonne réponse ci-dessous qui, malheureusement, ne semble pas s'appliquer. Cela vous a-t-il aidé à ce moment-là? Si vous pouvez y répondre, votez-y ou acceptez-le, ce qui est généralement considéré comme une bonne pratique ici. Mieux vaut tard que jamais? – halfer

Répondre

2

La question clé est que vous utilisez sqrt, qui ne peut pas gérer les nombres négatifs, parce que le résultat est un nombre imaginaire. Donc, il est dit que ce n'est "pas un nombre" (nan). Par exemple, 3 - sqrt(4) est 1, mais 3 - sqrt(-4) est vraiment 3 - 2i. Mais la fonction sqrt ne peut pas le faire pour vous, vous devez donc soit utiliser une bibliothèque qui gère les nombres imaginaires, soit gérer vous-même manuellement.

Quelques questions sans rapport avec l'erreur nan:

  1. Vous définissez firstXValueInt (et les autres Int semblables variables) basée sur le contenu de firstXValueVAR, mais, Après avoir fait cela, vous récupérez firstXValueVAR à partir du UITextField. Cela semble en arrière. Commencez par récupérer les valeurs du champ de texte, puis commencez à faire vos calculs. Vous convertissez la valeur de votre champ de texte en Double puis en la convertissant en Int afin de la définir à l'aide d'un opérateur de décalage bit à bit. Bien sûr, vous pouvez le faire si vous êtes assuré que les valeurs ne contiendront jamais des valeurs non-entières, mais c'est une énorme contrainte à imposer juste pour que vous puissiez profiter de l'efficacité de l'opération de décalage bit à bit. De plus, cette opération au niveau du bit ne fait pas ce que je pense que vous pensez qu'elle fait. Le << 2 équivaut à multiplier par quatre, ne pas la quadrature.

  2. Et si vous êtes vraiment soucieux de l'efficacité, je ne recalculerais pas le discriminant plusieurs fois. Personnellement, je suggère de perdre cette conversion entière et éviter toute une catégorie de problèmes possibles.

  3. Je ne comprends pas pourquoi vous semblez répéter le code pour le calcul de totalX et totalX2 quatre fois sur la base de la valeur de la firstOperationValue. Et si vous allez faire cela, je passerais soit à un modèle if - else if (ou, mieux, une instruction switch) et ensuite avoir une clause default pour détecter si aucune des quatre valeurs attendues ne sont trouvées.

Quoi qu'il en soit, si je voulais les racines de cette formule quadratique, je ferais quelque chose comme:

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)") 
} 

Note, la prend sa retraite avant tout de ces propriétés et utilise uniquement des variables locales (autres que les contrôles UITextField). Vous pouvez minimiser les conséquences inattendues en vous assurant que vous n'utilisez que des propriétés là où vous en avez vraiment besoin, et je garderais personnellement tous les calculs en tant que variables locales. Personnellement, j'éviterais également l'utilisation du déballage forcé (le !) et ferais une liaison conditionnelle pour gérer gracieusement les valeurs nil, mais c'est à vous de décider.