0

I have a fraction calculator and when I calculate it, it turns into a decimal. I want to turn it into a fraction. I don't know how to do it in code but I tried separating the calculations but it wouldn't work here is the code with a screenshot of my storyboard https://www.dropbox.com/s/fmapxaou49zap05/iOS%20Simulator%20Screen%20Shot%20Oct%2015%2C%202014%2C%209.37.43%20PM.png?dl=0

        //Adding Function
        changingSignsLabel.text = "+"
        let firstDenomInTextField:Double! = (firstDenominatorTextField.text as NSString).doubleValue
        let firstNumInTextField:Double! = (firstNumeratorTextField.text as NSString).doubleValue
        let firstWholeInTextField:Double! = (firstWholeNumberTextField.text as NSString).doubleValue

        let secondDenomInTextField:Double! = (secondDenominatorTextField.text as NSString).doubleValue
        let secondNumInTextField:Double! = (secondNumeratorTextField.text as NSString).doubleValue
        let secondWholeInTextField:Double! = (secondWholeNumberTextField.text as NSString).doubleValue

        var firstStep = firstDenomInTextField! * firstWholeInTextField! / firstDenomInTextField!

        var secondStep = firstStep + firstNumInTextField! / firstDenomInTextField!

        var thirdStep = secondDenomInTextField! * secondWholeInTextField! / secondDenomInTextField!
        var fourthStep = thirdStep + secondNumInTextField! / secondDenomInTextField!

        var calculatedAnswer = (secondStep + fourthStep)

        answerLabel.hidden = false

        answerLabel.text = "\(calculatedAnswer)"

If you have any questions or concerns please comment them down below

Thank you for your help

alex
  • 1,746
  • 6
  • 19
  • 34
  • You already have the numerator and denominator, isn't that the fraction? numerator / denominator ? Am I misunderstanding your question? Or are you asking how to change 12/8 into 1 and 1/2 ? – Zhang Oct 16 '14 at 04:41
  • No, when I calculate it, it is in decimal form, I want to somehow get it into a fraction form @Zhang – alex Oct 16 '14 at 04:50
  • 2
    I hope you're not trying to convert the decimal back into fraction form because you do realise floating point values are rounded off on the computer? – Zhang Oct 16 '14 at 05:14

3 Answers3

7

For this to work every time, you want to use the Euclidian Algorithm, which in swift looks like this:

func simplify(top:Int, bottom:Int) -> (newTop:Int, newBottom:Int) {

    var x = top
    var y = bottom
    while (y != 0) {
        var buffer = y
        y = x % y
        x = buffer
    }
    var hcfVal = x
    var newTopVal = top/hcfVal
    var newBottomVal = bottom/hcfVal
    return(newTopVal, newBottomVal)
}

You should just be able to add this to your program, then call it with:

simplify(5,10)

...returning 1 and 2. Hope this helps anyone else trying to find a simpler answer to this question.

CarveDrone
  • 915
  • 1
  • 9
  • 23
  • i have an updating number assigned to a variable name calculated answer like this `5 * 2` how can i use the function so that it is a variable for the top and for the bottom 100 – alex Nov 04 '14 at 16:17
  • So are you saying you have a fraction calculatedAnswer/100? To use this you would add the function somewhere in your code, then call it with var answer = simplify(calculatedAnswer, 100), then your top value would be answer.0 and your bottom would be answer.1 @Grapeapplesauce – CarveDrone Nov 04 '14 at 16:20
  • Can you update your function so it works with Doubles not Ints? Because my app runs on the variables being type: Double – alex Nov 04 '14 at 16:27
  • No, you have to convert doubles to ints to use this function, – CarveDrone Nov 04 '14 at 16:31
  • example: simplify(Int(xValue), Int(doublesHere)) – CarveDrone Nov 04 '14 at 16:32
3

Updated Answer

I wrote you a demo app:

Demo App Screenshot

Swift Source Code:

Put this inside your view controller.

var numeratorField:UITextField?;
var denominatorField:UITextField?;
var equalButton:UIButton?;
var wholeNumberLabel:UILabel?;
var numeratorLabel:UILabel?;
var denominatorLabel:UILabel?;
var dividerLine:UIView?;

var appName:UILabel?;
var instructions:UILabel?;


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

    initViews();
    initConstraints();
}

// ---------------------------------------------------------------------
// MARK: Interface Setup
// ---------------------------------------------------------------------

func initViews()
{
    self.numeratorField = UITextField();
    self.numeratorField?.layer.cornerRadius = 5.0;
    self.numeratorField?.layer.borderWidth = 1.0;
    self.numeratorField?.textAlignment = NSTextAlignment.Center;

    self.denominatorField = UITextField();
    self.denominatorField?.layer.cornerRadius = 5.0;
    self.denominatorField?.layer.borderWidth = 1.0;
    self.denominatorField?.textAlignment = NSTextAlignment.Center;

    self.equalButton = UIButton();
    self.equalButton?.setTitle("=", forState: UIControlState.Normal);
    self.equalButton?.addTarget(self, action: "calculateAnswer", forControlEvents: UIControlEvents.TouchUpInside);
    self.equalButton?.setTitleColor(UIColor.darkGrayColor(), forState: UIControlState.Normal);
    self.equalButton?.layer.cornerRadius = 5.0;
    self.equalButton?.backgroundColor = UIColor.lightGrayColor();

    self.wholeNumberLabel = UILabel();
    self.wholeNumberLabel?.textAlignment = NSTextAlignment.Right;
    self.wholeNumberLabel?.font = UIFont(name: "HelveticaNeue", size: 20);

    self.numeratorLabel = UILabel();
    self.numeratorLabel?.textAlignment = NSTextAlignment.Center;
    self.numeratorLabel?.font = UIFont(name: "HelveticaNeue", size: 14);

    self.denominatorLabel = UILabel();
    self.denominatorLabel?.textAlignment = NSTextAlignment.Center;
    self.denominatorLabel?.font = UIFont(name: "HelveticaNeue", size: 14);

    self.dividerLine = UIView();
    self.dividerLine?.backgroundColor = self.numeratorLabel!.textColor;
    self.dividerLine?.alpha = 0;

    self.appName = UILabel();
    self.appName?.text = "Fraction App";
    self.appName?.font = UIFont(name: "HelveticaNeue-Bold", size: 24);
    self.appName?.textAlignment = NSTextAlignment.Center;

    self.instructions = UILabel();
    self.instructions?.textAlignment = NSTextAlignment.Center;
    self.instructions?.text = "Enter a value in the numerator and denominator field, then press the equal sign to see the answer";
    self.instructions?.numberOfLines = 0;
    self.instructions?.lineBreakMode = NSLineBreakMode.ByWordWrapping;

    self.view.addSubview(self.numeratorField!);
    self.view.addSubview(self.denominatorField!);
    self.view.addSubview(self.equalButton!);
    self.view.addSubview(self.wholeNumberLabel!);
    self.view.addSubview(self.numeratorLabel!);
    self.view.addSubview(self.denominatorLabel!);
    self.view.addSubview(self.dividerLine!);
    self.view.addSubview(self.appName!);
    self.view.addSubview(self.instructions!);
}

func initConstraints()
{
    self.appName?.setTranslatesAutoresizingMaskIntoConstraints(false);
    self.numeratorField?.setTranslatesAutoresizingMaskIntoConstraints(false);
    self.denominatorField?.setTranslatesAutoresizingMaskIntoConstraints(false);
    self.equalButton?.setTranslatesAutoresizingMaskIntoConstraints(false);
    self.wholeNumberLabel?.setTranslatesAutoresizingMaskIntoConstraints(false);
    self.numeratorLabel?.setTranslatesAutoresizingMaskIntoConstraints(false);
    self.denominatorLabel?.setTranslatesAutoresizingMaskIntoConstraints(false);
    self.dividerLine?.setTranslatesAutoresizingMaskIntoConstraints(false);
    self.instructions?.setTranslatesAutoresizingMaskIntoConstraints(false);

    var views:NSMutableDictionary = NSMutableDictionary();
    views.setValue(self.appName, forKey: "appName");
    views.setValue(self.numeratorField, forKey: "numeratorField");
    views.setValue(self.denominatorField, forKey: "denominatorField");
    views.setValue(self.equalButton, forKey: "equalButton");
    views.setValue(self.wholeNumberLabel, forKey: "wholeNumberLabel")
    views.setValue(self.numeratorLabel, forKey: "numeratorLabel");
    views.setValue(self.denominatorLabel, forKey: "denominatorLabel");
    views.setValue(self.dividerLine, forKey: "dividerLine");
    views.setValue(self.instructions, forKey: "instructions");

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[appName]|", options: nil, metrics: nil, views: views));
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-50-[appName]", options: nil, metrics: nil, views: views));

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[instructions]-20-|", options: nil, metrics: nil, views: views));
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[instructions]-100-|", options: nil, metrics: nil, views: views));

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-35-[numeratorField(75)]-10-[denominatorField(==numeratorField)]-10-[equalButton]-10-[wholeNumberLabel(>=20)]-2-[dividerLine(15)]", options: nil, metrics: nil, views: views));

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[numeratorField(50)]", options: nil, metrics: nil, views: views));
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[denominatorField(==numeratorField)]", options: nil, metrics: nil, views: views));
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[equalButton(==numeratorField)]", options: nil, metrics: nil, views: views));
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[wholeNumberLabel(==numeratorField)]", options: nil, metrics: nil, views: views));
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[numeratorLabel]", options: nil, metrics: nil, views: views));
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[denominatorLabel]", options: nil, metrics: nil, views: views));
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[dividerLine(1)]", options: nil, metrics: nil, views: views));

    self.view.addConstraint(NSLayoutConstraint(item: self.numeratorLabel!, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.wholeNumberLabel, attribute: NSLayoutAttribute.Right, multiplier: 1.0, constant: 0.0));
    self.view.addConstraint(NSLayoutConstraint(item: self.denominatorLabel!, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.wholeNumberLabel, attribute: NSLayoutAttribute.Right, multiplier: 1.0, constant: 0.0));

    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[numeratorLabel(==wholeNumberLabel)]", options: nil, metrics: nil, views: views));
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[denominatorLabel(==wholeNumberLabel)]", options: nil, metrics: nil, views: views));



    self.view.addConstraint(NSLayoutConstraint(item: self.numeratorField!, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0.0));
    self.view.addConstraint(NSLayoutConstraint(item: self.denominatorField!, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0.0));
    self.view.addConstraint(NSLayoutConstraint(item: self.equalButton!, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0.0));
    self.view.addConstraint(NSLayoutConstraint(item: self.wholeNumberLabel!, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0.0));
    self.view.addConstraint(NSLayoutConstraint(item: self.dividerLine!, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0.0));

    self.view.addConstraint(NSLayoutConstraint(item: self.numeratorLabel!, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.wholeNumberLabel, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0.0));
    self.view.addConstraint(NSLayoutConstraint(item: self.denominatorLabel!, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.wholeNumberLabel, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0.0));
}

func getLowestCommonDenominator(Numerator numerator:Int, Denominator denominator:Int) -> Int
{
    var finalDenominator = denominator;

    //println("\(numerator) / \(finalDenominator) = \(numerator % finalDenominator)");

    if(numerator % 2 == 0 && finalDenominator % 2 == 0) // even number
    {
        return self.getLowestCommonDenominator(Numerator: numerator / 2.0, Denominator: finalDenominator / 2.0);
    }
    else if(numerator % 3 == 0 && finalDenominator % 3 == 0) // odd number
    {
        return self.getLowestCommonDenominator(Numerator: numerator / 3.0, Denominator: finalDenominator / 3.0);
    }
    else // prime number, always have a remainder
    {
        //println("lowest common denominator = \(finalDenominator)");

        return finalDenominator;
    }
}

func calculateAnswer()
{
    // prevent division by zero
    if(self.denominatorField?.text == "0")
    {
        var alert:UIAlertView = UIAlertView(title: "Division By Zero", message: "Divide by zero yields undefined value", delegate: self, cancelButtonTitle: "OK");
        alert.show();

        return;
    }

    // clear previous values;
    self.wholeNumberLabel?.text = "";
    self.numeratorLabel?.text = "";
    self.denominatorLabel?.text = "";

    var numeratorString:NSString = self.numeratorField!.text;
    var denominatorString:NSString = self.denominatorField!.text;

    if (numeratorString.length == 0 || denominatorString.length == 0)
    {
        //var alert:UIAlertView = UIAlertView(title: "Input Missing", message: "Enter a value for numerator and denominator then press the equal sign to get the answer", delegate: nil, cancelButtonTitle: "OK", otherButtonTitles: nil, nil);

        var alert:UIAlertView = UIAlertView(title: "Input Missing", message: "Enter a value for numerator and denominator then press the equal sign to get the answer", delegate: nil, cancelButtonTitle: "OK");

        alert.show();
    }
    else
    {
        var shouldShowWholeParts:Bool = false;
        var shouldShowFractionParts:Bool = false;

        var numerator:Int = self.numeratorField!.text.toInt()!;
        var denominator:Int = self.denominatorField!.text.toInt()!;

        var finalNumerator = numerator;
        var finalDenominator = self.getLowestCommonDenominator(Numerator: numerator, Denominator: denominator);

        if(finalDenominator < denominator)
        {
            denominator = finalDenominator;
            numerator = numerator / finalDenominator;
        }

        var wholeNumbers:Int = numerator / denominator;
        var remainder:Int = numerator % denominator;

        //println("wholeNumbers = \(wholeNumbers), remainder = \(remainder)");
        //println("\(denominator) % \(remainder) = \(denominator % remainder)");

        if(wholeNumbers != 0)
        {
            shouldShowWholeParts = true;
        }
        else
        {
            shouldShowWholeParts = false;
        }

        if(remainder > 0)
        {
            // see if we can simply the fraction part as well
            if(denominator % remainder == 0) // no remainder means remainder can be simplified further
            {
                finalDenominator = denominator / remainder;
                finalNumerator = remainder / remainder;
            }
            else
            {
                finalNumerator = remainder;
                finalDenominator = denominator;
            }

            shouldShowFractionParts = true;
        }
        else
        {
            shouldShowFractionParts = false;
        }

        var answer:NSString?;

        if(wholeNumbers > 0 && remainder > 0)
        {
            answer = NSString(format: "\(wholeNumbers) \(finalNumerator)/\(finalDenominator)");

            // prints out whole number and fraction parts
            //println("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers) \(finalNumerator)/\(finalDenominator)");
        }
        else if (wholeNumbers > 0 && remainder == 0)
        {
            answer = NSString(format: "\(wholeNumbers)");

            // prints out whole number only
            //println("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers)");
        }
        else
        {
            answer = NSString(format: "\(finalNumerator)/\(finalDenominator)");

            // prints out fraction part only
            //println("Simplified fraction of \(numerator)/\(denominator) = \(finalNumerator)/\(finalDenominator)");
        }

        if(shouldShowWholeParts)
        {
            self.wholeNumberLabel?.text = NSString(format: "\(wholeNumbers)");
        }

        if(shouldShowFractionParts)
        {
            self.numeratorLabel?.text = NSString(format: "\(finalNumerator)");
            self.denominatorLabel?.text = NSString(format: "\(finalDenominator)");
            self.dividerLine?.alpha = 1;
        }
        else
        {
            self.dividerLine?.alpha = 0;
        }


    }
}

Original Answer

Is this what you're looking for?

Results:

Simplified fraction of 7/8 = 7/8
Simplified fraction of 12/8 = 1 1/2
Simplified fraction of 5/16 = 5/16
Simplified fraction of 342/23 = 14 20/23
Simplified fraction of 129/72 = 1 57/72

Source Code:

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

    printSimplifiedFraction(Numerator: 7, Denominator: 8);
    printSimplifiedFraction(Numerator: 12, Denominator: 8);
    printSimplifiedFraction(Numerator: 5, Denominator: 16);
    printSimplifiedFraction(Numerator: 342, Denominator: 23);
    printSimplifiedFraction(Numerator: 129, Denominator: 72);
}

func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator:Int)
{
    var finalNumerator = numerator;
    var finalDenominator = denominator;

    var wholeNumbers:Int = numerator / denominator;
    var remainder:Int = numerator % denominator;

    //println("wholeNumbers = \(wholeNumbers), remainder = \(remainder)");
    //println("\(denominator) % \(remainder) = \(denominator % remainder)");

    if(remainder > 0)
    {
        // see if we can simply the fraction part as well
        if(denominator % remainder == 0) // no remainder means remainder can be simplified further
        {
            finalDenominator = denominator / remainder;
            finalNumerator = remainder / remainder;
        }
        else
        {
            finalNumerator = remainder;
            finalDenominator = denominator;
        }
    }

    if(wholeNumbers > 0 && remainder > 0)
    {
        // prints out whole number and fraction parts
        println("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers) \(finalNumerator)/\(finalDenominator)");
    }
    else if (wholeNumbers > 0 && remainder == 0)
    {
        // prints out whole number only
        println("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers)");
    }
    else
    {
        // prints out fraction part only
        println("Simplified fraction of \(numerator)/\(denominator) = \(finalNumerator)/\(finalDenominator)");
    }
}
Zhang
  • 11,549
  • 7
  • 57
  • 87
  • Just copy the whole function printSimplifiedFraction and paste into your code, then you can call it anywhere if your view controller. – Zhang Oct 16 '14 at 05:16
  • I want the user to enter in their own Numerator and Denominator how do I do that instead of me doing it myself? Is that possible? – alex Oct 16 '14 at 05:17
  • Sorry, previous Swift source code had errors. I've updated the code with a more robust answer that takes into consideration division by zero and uses lowest common denominator, so 15/9 should yield 1 2/3 instead of 1 6/9 :D – Zhang Oct 16 '14 at 07:28
  • 2
    Your `getLowestCommonDenominator()` function finds only 2 and 3 as common factors, so 35/55 would not be simplified to 7/11. The proper method to reduce a fraction is to compute the "greatest common divisor" using the "Euklidean Algorithm". – Martin R Oct 16 '14 at 08:24
  • Thanks for pointing that out @MartinR, I didn't know that. I myself, am not that talented to understand this scary calculus: http://mathworld.wolfram.com/EuclideanAlgorithm.html so if Grapeapplesauce wants to take a stab, by all means go ahead, but if you give up, here's a Java implementation of the Euclidean Algorithm I found on another Stackoverflow post: http://stackoverflow.com/questions/6005582/how-does-the-euclidean-algorithm-work Good luck :D – Zhang Oct 17 '14 at 02:03
1

Unfortunately there is not framework you can import to display a fraction in swift or Xcode. What I would recommend is using the same method you used in your storyboard: Have two UILabelView's, one on top of each other, with a line between them.

Instead of calculating the decimal, use basic math to find the numerator and denominator and display them on the top and bottom of the UILabelView.

This method will require changing your program at a fundamental level, however it will work.

Mario Jimenez
  • 203
  • 1
  • 8
  • Could you show an example, because when you add 2 and 4/5 and 2 and 3/5 you would have an overflow of the fraction so you add 1 to the whole number so the answer to 2 4/5 + 2 3/5 = 5 2/5 – alex Oct 16 '14 at 04:54
  • do you get what I'm trying to say? – alex Oct 16 '14 at 05:07
  • In this instance, what you would need to do is create a function that takes the whole number, the numerator, and the denominator and does the calculation, then returns each individual number to its value, respectively. For instance to create a function to add two fractions together, the easiest way I can think of is to follow these steps: http://www.decodedscience.com/adding-fractions-using-a-common-denominator/24006 – Mario Jimenez Oct 16 '14 at 06:00
  • I know, and I've been trying to do that but I don't know how do you? – alex Oct 16 '14 at 06:07
  • I can't comment on Zhang's Post, because stack overflows silly rules about reputation. However Zhang's code should work for you. If you want the user to input the values, simply use UITextFields, link them to your code (control drag them to your code), then retrieve the values in the code by saying: `@IBOutlet weak var numerator: UITextField!` `var number = numerator.text.toInt()` – Mario Jimenez Oct 16 '14 at 06:22
  • There is now! I wrote FractionFormatter to solve this for my own app. https://swiftpackageregistry.com/davidwkeith/FractionFormatter – David W. Keith Jun 07 '23 at 22:37