Multiplying, subtracting and dividing binary numbers give wrong answers - swift

I'm making a binary calculator app.
No buildtime issues but in the app only adding binary numbers give the right answer, multiplying, subtracting and dividing don't.
Dividing - every answer = 1 (1010-0001 = 1; 10101010-1010 = 1)
Multiplying - every answer is wrong, (11111 x 101010 = 1111000001, should be 10100010110)
Subtracting - every answer = 0 ( 1010-0001 = 0; 1010101-0001 = 0)
I tried making the code more explanatory and it worked in the playground (ending with print() ) but when I changed the apps code, the answers were the same.
var numberOnScreen:Int = 0;
var previousNumber:Int = 0;
var doingMath = false
var operation = 0;
var decimal = 0;
var decimal1 = 0;
var binary:String = ""
var binary1:String = ""
#IBOutlet weak var label: UILabel!
#IBAction func Numbers(_ sender: UIButton) {
if doingMath == true
{
label.text = String(sender.tag-1)
numberOnScreen = Int(label.text!)!
doingMath = false
}
else
{
label.text = label.text! + String(sender.tag-1)
numberOnScreen = Int(label.text!)!
}
}
#IBAction func buttons(_ sender: UIButton) {
if label.text != "" && sender.tag != 6 && sender.tag != 8
{
previousNumber = Int(label.text!)!
binary = "\(previousNumber)"
decimal = Int(binary, radix: 2)!
binary1 = "\(numberOnScreen)"
decimal1 = Int(binary1, radix: 2)!
operation = sender.tag
doingMath = true;
}
else if sender.tag == 8
{
if operation == 3 //adding
{
label.text = String((decimal + decimal1), radix: 2)
}
else if operation == 4 //subtracting
{
label.text = String((decimal - decimal1), radix: 2)
}
else if operation == 5 //multiplying
{
label.text = String((decimal * decimal1), radix: 2)
}
else if operation == 7 //dividing
{
label.text = String((decimal / decimal1), radix: 2)
}

Related

Adding a Decimal Point button to the calculator app

Can someone please add the code to this so I'm able to add a decimal point button?
This is what I have so far, can someone please fill in the code required for the decimal point button. so I can learn from it. please view over the code and let me know what you think.
import UIKit
class ViewController: UIViewController {
var numberOnScreen:Double = 0;
var previousNumber:Double = 0;
var preformingMath = false
var operation = 0;
#IBOutlet weak var label: UILabel!
#IBAction func numbers(_ sender: UIButton)
{
if preformingMath == true
{
label.text = String(sender.tag-1)
numberOnScreen = Double(label.text!)!
preformingMath = false
}
else
{
label.text = label.text! + String(sender.tag-1)
numberOnScreen = Double(label.text!)!
}
}
#IBAction func buttons(_ sender: UIButton)
{
if label.text != "" && sender.tag != 11 && sender.tag != 16
{
previousNumber = Double(label.text!)!
if sender.tag == 12 //Divide
{
label.text = "/";
}
else if sender.tag == 13//Multiply
{
label.text = "x";
}
else if sender.tag == 14 //Minus
{
label.text = "-";
}
else if sender.tag == 15 //Plus
{
label.text = "+";
}
operation = sender.tag;
preformingMath = true;
}
else if sender.tag == 16
{
if operation == 12
{
label.text = String(previousNumber / numberOnScreen)
}
else if operation == 13
{
label.text = String(previousNumber * numberOnScreen)
}
else if operation == 14
{
label.text = String(previousNumber - numberOnScreen)
}
else if operation == 15
{
label.text = String(previousNumber + numberOnScreen)
}
}
else if sender.tag == 11
{
label.text = ""
previousNumber = 0;
numberOnScreen = 0;
operation = 0;
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Add this #IBAction to your code and hook it to your . button.
If the user presses . before any numbers, the display will be set to 0..
If there are numbers in the display, then . will be appended to the display if there isn't already a decimal point in the number.
Finally, the numberOnScreen will be updated.
#IBAction func decimal(_ sender: UIButton) {
if preformingMath || label.text!.isEmpty
{
label.text = "0."
preformingMath = false
}
else
{
if !label.text!.contains(".") {
label.text = label.text! + "."
}
}
numberOnScreen = Double(label.text!)!
}

Second variable takes the firsts value

I built an binary calculator app, For the numbers I have two variables. previousNumber and numberOnScreen. The idea is to convert the binary numbers to decimals, do the calculation and convert the answer back.
Lets say the first (previousNumber)number I pick is 1010 and the second (numberOnScreen) 10100
var numberOnScreen:Int = 0;
var previousNumber:Int = 0;
var doingMath = false
var operation = 0;
var decimal = 0;
var decimal1 = 0;
var binary:String = ""
var binary1:String = ""
#IBOutlet weak var label: UILabel!
#IBAction func Numbers(_ sender: UIButton) {
if doingMath == true
{
label.text = String(sender.tag-1)
numberOnScreen = Int(label.text!)!
doingMath = false
}
else
{
label.text = label.text! + String(sender.tag-1)
numberOnScreen = Int(label.text!)!
}
}
#IBAction func buttons(_ sender: UIButton) {
if label.text != "" && sender.tag != 6 && sender.tag != 8
{
previousNumber = Int(label.text!)!
binary = "\(previousNumber)"
decimal = Int(binary, radix: 2)!
binary1 = "\(numberOnScreen)"
decimal1 = Int(binary1, radix: 2)!
operation = sender.tag
doingMath = true;
}
else if sender.tag == 8
{
if operation == 3 //adding
{
print(previousNumber, numberOnScreen, decimal, decimal1)
It prints [ 1010, 10100, 10, 10 }
Any ideas why this is happening?
When you hit the = key, you need to update the calculation of decimal1. Move that code to the place where you are processing =:
#IBAction func buttons(_ sender: UIButton) {
if label.text != "" && sender.tag != 6 && sender.tag != 8
{
previousNumber = Int(label.text!)!
binary = "\(previousNumber)"
decimal = Int(binary, radix: 2)!
operation = sender.tag
doingMath = true;
}
else if sender.tag == 8
{
binary1 = "\(numberOnScreen)"
decimal1 = Int(binary1, radix: 2)!
if operation == 3 //adding
{
print(previousNumber, numberOnScreen, decimal, decimal1)
Also, I recommend that you get rid of the magic numbers in your code and replace them with constants. For your key tags, you could define a struct like this:
struct Key {
static let clear = 6
static let equals = 8
static let plus = 3
}
and then your code would read:
if label.text != "" && sender.tag != Key.clear && sender.tag != Key.equals {
which is much clearer.

Can't make calculator app in Swift get more than one digit?

So this is the class for my Operation:
class Calculation {
var currentNumber: String = ""
var resultNumber = Int()
var operationInput = String()
func operationIdentifier() {
if operationInput == "=" {
resultNumber = Int(currentNumber)!
print("\(resultNumber)")
} else if operationInput == "+" {
resultNumber += Int(currentNumber)!
print("\(resultNumber)")
} else if operationInput == "-" {
resultNumber -= Int(currentNumber)!
print("\(resultNumber)")
} else if operationInput == "*" {
resultNumber *= Int(currentNumber)!
print("\(resultNumber)")
} else if operationInput == "/" {
resultNumber /= Int(currentNumber)!
print("\(resultNumber)")
} else {
print("Operation does not exist.")
}
print("\(resultNumber)")
}
And this is where I get this button to get the title for numbers:
#IBAction func numberPressed(_ sender: UIButton) {
calculation.currentNumber = (sender.titleLabel?.text!)!
calculation.currentNumber.append(<#T##other: String##String#>)
//calculation.currentNumber.append((sender.titleLabel?.text)!) This is how I use it to append.
calculation.operationIdentifier()
resultTextField.text = "\(calculation.currentNumber)"
}
The append command is for strings as showed in the code section which I use to add to the end of the previous number, and the result is always a double of some Int e.g : If you press 5, it returns 55.
First of all, you are overwriting value here: calculation.currentNumber = (sender.titleLabel?.text!)!. Second, you will need to clear a current number after pressing.
Here is my concept for you(your edited code), you can try it in Playground.
enum Operator: String {
case plus = "+"
case minus = "-"
case multiply = "*"
case divide = "/"
case equal = "="
}
class Calculation {
var currentNumber: String = ""
var resultNumber = Int()
var operationInput = String()
func recalculate() {
if resultNumber == 0 {
resultNumber = Int(currentNumber) ?? 0
return
}
guard let sign = Operator(rawValue: operationInput), let number = Int(currentNumber) else { return }
switch sign {
case .plus: resultNumber += number
case .minus: resultNumber -= number
case .divide: resultNumber /= number
case .multiply: resultNumber *= number
case .equal: resultNumber = number
}
}
func operatorPressed(_ op: Operator) {
recalculate()
operationInput = op.rawValue
currentNumber = ""
print(resultNumber)
}
func numberPressed(_ number: String) {
currentNumber.append(number)
}
}
let c = Calculation()
c.numberPressed("5")
c.numberPressed("5")
c.operatorPressed(.plus)
c.numberPressed("5")
c.operatorPressed(.multiply)
c.numberPressed("5")
c.operatorPressed(.equal)
c.operatorPressed(.plus)
c.numberPressed("5")
c.operatorPressed(.equal)
In numberPressed you are setting currentNumber in from the label text and then appending the same value to it again. It should be something like:
#IBAction func numberPressed(_ sender: UIButton) {
guard let label = sender.titleLabel, let numberString = label.text else{
return
}
calculation.currentNumber.append(numberString)
print("currentNumber = \(calculation.currentNumber)")
}
Also, why do you call calculation.operationIdentifier() in numberPressed? Wouldn't that go in an operatorPressed method?

Swift Calculator works perfectly but not when preforming a fresh operation

I have been spending the day today getting familiar with swift and I decided to try to build a calculator. I have the entire thing working except for one issue:
1 + 1 will return 2 to the label (this is fine)
But when I attempt to type a new number, example 1, the string gets appended to 21 instead of clearing the label and placing a singular 1
This occurs because I wanted to add the option for the operators to keep adding ex:
1 + 1 returns 2 then the user types + 3 to get a result of 5
The only issue is I dont know how to clear the label only when a new number is being entered after the equal sign is pressed
Here is the code of the view controller Hopefully I do not have to think of a completely different approach.
import UIKit
class ViewController: UIViewController {
var num1 = ""
var num2 = ""
var finalString = ""
var isFirstNumber = true
var hasFinalString = false
var isClear = true
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBOutlet weak var LBLOutput: UILabel!
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btrNumberClick(_ sender: UIButton) {
if isClear {
LBLOutput.text = ""
isClear = false
}
let currentText = LBLOutput.text!
let textLabel = sender.titleLabel?.text
if let text = textLabel {
switch text {
case "+", "x", "/", "-","%":
if hasFinalString {
return
}
finalString = text
isFirstNumber = false
hasFinalString = true
LBLOutput.text = "\(currentText) \(finalString) "
break
case "=":
isFirstNumber = true
hasFinalString = false
isClear = true
let result = calculate()
LBLOutput.text = "\(result)"
num1 = "\(result)"
break
default:
if isFirstNumber {
num1 = "\(num1)\(text)"
} else {
num2 = "\(num2)\(text)"
}
LBLOutput.text = "\(currentText)\(text)"
break;
}
}
}
func calculate() -> Double {
let firstNumber = Double(num1)!
let secondNumber = Double(num2)!
num1 = ""
num2 = ""
isClear = false
switch finalString {
case "+":
return firstNumber + secondNumber
case "-":
return firstNumber - secondNumber
case "x":
return firstNumber * secondNumber
case "/":
return firstNumber / secondNumber
case "%":
return (firstNumber * 100) / secondNumber
default:
return 0
}
}
#IBAction func clearTheLabel(_ sender: Any) {
num1 = ""
num2 = ""
LBLOutput.text = "0"
isClear = true
}
}
Why won't this work?
default:
if isFirstNumber {
LBLOutput.text = ""
num1 = "\(num1)\(text)"
LBLOutput.text = num1
} else {
num2 = "\(num2)\(text)"
LBLOutput.text = "\(currentText)\(text)"
}
break;
}
If isFirstNumber is true only after = is pressed then clearing then seems right. I hope I'm understanding your problem.
BTW: The Stanford course with the calculator example hooks all the buttons up to one IBAction as you've done. I think the switch statement is very clear and made for examples like this.

UILabel returns "nil"?

I am having trouble with my UIButton. For Example, when I click the the UIButton Number3 and hit the checkButton on the ViewController the result in the currentCountLabel is Optional(3). It does this for every number after I click the checkButton. If I then click the button again, the currentCountLabel says, "nil". Here is all of my code:
ViewController.swift:
class ViewController: UIViewController {
var currentCountLabel: UILabel = UILabel()
var currentCount: Int = 0
var IncorrectLabel: UILabel = UILabel()
var CorrectLabel: UILabel = UILabel()
var currectAmountCorrect : Int = 0
var currentAmountIncorrect : Int = 0
var flashTimer : NSTimer = NSTimer()
var timerCounter : Int = 0
var randomImageGeneratorNumber : Int = 0
var flashingImageView: UIImageView = UIImageView()
var flashButton: UIButton = UIButton()
var currentTime = NSTimer()
func timerFunc() {
flashButton.hidden = !flashButton.hidden
flashingImageView.hidden = !flashingImageView.hidden
}
#IBAction func flashButton(sender: UIButton) {
flashButton.hidden = !flashButton.hidden
flashingImageView.hidden = !flashingImageView.hidden
flashingImageView.image = UIImage(named: "Image\(arc4random_uniform(6) + 1).png")
if (flashingImageView.image == UIImage(named: "Image1")){
randomImageGeneratorNumber == 1
}
if (flashingImageView.image == UIImage(named: "Image2")){
randomImageGeneratorNumber == 2
}
if (flashingImageView.image == UIImage(named: "Image3")){
randomImageGeneratorNumber == 3
}
if (flashingImageView.image == UIImage(named: "Image4")){
randomImageGeneratorNumber == 4
}
if (flashingImageView.image == UIImage(named: "Image5")){
randomImageGeneratorNumber == 5
}
if (flashingImageView.image == UIImage(named: "Image6")){
randomImageGeneratorNumber == 6
}
currentCount = 0
currentCountLabel.text = "\(currentCount)"
if (flashButton.hidden == true){
flashButton.hidden = true;
flashingImageView.hidden = false
}
var currentTime = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "timerFunc", userInfo: nil, repeats: false)
func timerFunc(){
self.flashingImageView.hidden = true;
flashButton.hidden = !flashButton.hidden
flashingImageView.hidden = !flashingImageView.hidden
}
}
#IBAction func checkButton(sender: UIButton) {
if (flashButton.hidden == true){
flashButton.hidden == false
flashingImageView.hidden == true
}
var currentCount = currentCountLabel.text?.toInt()
if randomImageGeneratorNumber == currentCount {
currectAmountCorrect += 1
CorrectLabel.text = "\(currectAmountCorrect)"
} else {
currentAmountIncorrect += 1
IncorrectLabel.text = "\(currentAmountIncorrect)"
}
if (currentCountLabel.text == "0"){
let alert = UIAlertView()
alert.title = "Alert"
alert.message = "You must type in an answer in order to check it"
alert.addButtonWithTitle("Understood")
alert.show()
}
currentCount == 0
currentCountLabel.text = "\(currentCount)"
}
#IBAction func clearButton(sender: UIButton) {
currentCount = 0
currentCountLabel.text = "\(currentCount)"
}
#IBAction func Number1Button(sender: UIButton) {
currentCount = currentCount * 10
currentCount = currentCount + 1
currentCountLabel.text = "\(currentCount)"
}
#IBAction func Number2Button(sender: UIButton) {
currentCount = currentCount * 10
currentCount = currentCount + 2
currentCountLabel.text = "\(currentCount)"
}
#IBAction func Number3Button(sender: UIButton) {
currentCount = currentCount * 10
currentCount = currentCount + 3
currentCountLabel.text = "\(currentCount)"
}
#IBAction func Number4Button(sender: UIButton) {
currentCount = currentCount * 10
currentCount = currentCount + 4
currentCountLabel.text = "\(currentCount)"
}
#IBAction func Number5Button(sender: UIButton) {
currentCount = currentCount * 10
currentCount = currentCount + 5
currentCountLabel.text = "\(currentCount)"
}
#IBAction func Number6Button(sender: UIButton) {
currentCount = currentCount * 10
currentCount = currentCount + 6
currentCountLabel.text = "\(currentCount)"
}
override func viewDidLoad() {
super.viewDidLoad()
var currentCountLabel = "\(currentCount)"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I have no idea what so ever is happening or how to fix it.
Any input and suggestions would be greatly appreciated.
Thanks in advance.
It would help if you clarified how you want it to behave. If you're wondering why it's an optional and why it's returning nil then you can fix this as follows.
In your checkButton() function you have this line at the end:
currentCountLabel.text = "\(currentCount)"
Unwrap the currentCount variable to this:
currentCountLabel.text = "\(currentCount!)"
Within this same checkButton() function you have this line:
currentCount == 0
So if you're wondering why it's not returning 0 it's because you're using a comparison operator not an assignment operator.