0

Firstly Thanks to all upcoming answers .

I am new to swift programming . I am testing out many things lol . I am trying to do a bmi app. I am using print() in order to check all values of my variables. I am not able to understand why imc value is 0 . Did I miss something ? What's the logic? I tried to hard code it with quotien 90/32400 or x/ySquare same result. I am still getting quotien = 0

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var weightTextField: UITextField!
    @IBOutlet weak var heightTextfield: UITextField!
    @IBOutlet weak var resultLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func calculateButton(_ sender: Any) {
        imcCalculator()
    }


    func imcCalculator () {
        let myHeight = Int(heightTextfield.text!)
        let myWeight = Int(weightTextField.text!)
        let x = myWeight!
        let y = myHeight!

        //let imc =  Int(Int(x / pow(y, 2)) * 10000)
        let ySquare = y * y
        let quotien = 90 / 32400
        let imc = (x/ySquare)*10000
        if imc > 25 {
            resultLabel.text = " Your BMI is \(imc) . You are overweight"
        }    
        else if imc  18 {
            resultLabel.text = " Your BMI is \(imc) . You have a normal weight"
        }
        else {
            resultLabel.text = "Your BMI is \(imc) . You are underweight"
        }
        print(x)
        print(y)
        print(ySquare)
        print(quotien)
        print(imc)
    }
}
Paul R
  • 208,748
  • 37
  • 389
  • 560
Vangola
  • 128
  • 7

1 Answers1

1

What's happening is called Truncation, or Integer division. The result of integer division differs from language to language. And as stated by the Swift docs:

For integer types, any remainder of the division is discarded

That's why let quotien = 90 / 32400 will give 0 as a result.

I would suggest you use Doubles instead, and your code might look like this:

func imcCalculator () {

    guard let myHeight = Double("6"), let myWeight = Double("70") else {
        fatalError("Error in the text fields")
    }

    let x = myWeight
    let y = myHeight

    //let imc =  Int(Int(x / pow(y, 2)) * 10000)
    let ySquare: Double = y * y
    let quotien: Double = 90.0 / 32400.0
    let imc: Double = (myHeight / ySquare) * 10000

    let imcString: String = String(format: "Your BMI is %.2d", imc)

    if imc > 25 {
        resultLabel.text = imcString + " . You are overweight"
    }
    else if imc < 25 && imc > 18 {
        resultLabel.text = imcString + " . You have a normal weight"
    }
    else {
        resultLabel.text = imcString + " . You are underweight"
    }

    print("x =", x)
    print("y =", y)
    print("ySquare =", ySquare)
    print("quotien =", quotien)
    print("imc =", imc)
}

The point is: Arithmetic operations between elements of a certain type, give results of the same type.

Thus, when dividing for example 1 by 2, you should expect the result to be an integer too. And it's a convention to define the integer part of the quotient as the result of the division of the two numbers. 1 divided by 2 (in real number division) gives 0.5, the integer part of that is 0.

On the other hand, 1.0/2.0 is 0.5 since both the Dividend and Divisor are infered to be Doubles. If you don't add the .0 after at least one them, thene fractional part is discarded.

You can try this in a playground:

3/10          //0
3.0/10.0      //0.3
3.0/10        //0.3
3/10.0        //0.3

As noted by @Martin R, the result of integer division differs from the quotient of Euclidean division when the Dividend (numerator) is negative, since truncation always rounds toward zero. Here is what is meant by that:

  • In integer division: (-3)/10 equals 0

  • In Euclidean division: The quotient of (-3)/10 is -1

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
ielyamani
  • 17,807
  • 10
  • 55
  • 90