Comma not working

Hello
Do you know why the comma in this calculator app isn't working:
Code Block
import SwiftUI
import Combine
enum Nums: String{
case uno = "1"
case due = "2"
case tre = "3"
case quattro = "4"
case cinque = "5"
case sei = "6"
case sette = "7"
case otto = "8"
case nove = "9"
case zero = "0"
case moltiplicazione = "X"
case divisione = "/"
case somma = "+"
case meno = "-"
case uguale = "="
case AC = "AC"
case piùMeno = "±"
case percentuale = "%"
case virgola = "."
case niente = ""
}
struct ContentView: View {
var numeri: [[Nums]] = [
[Nums.AC, Nums.piùMeno, Nums.percentuale, Nums.divisione],
[Nums.sette, Nums.otto, Nums.nove, Nums.moltiplicazione],
[Nums.quattro, Nums.cinque, Nums.sei, Nums.meno],
[Nums.uno, Nums.due, Nums.tre, Nums.somma],
[Nums.zero, Nums.niente, Nums.virgola, Nums.uguale]
]
private var gridItemLayout = [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())]
@State var previousVar: Double = 0
let timer = Timer.publish(every: 0.001, on: .main, in: .common).autoconnect()
@State var con: Int = 0
@State var final: Double = 0
@State var operat = Nums(rawValue: "")
@State var digits: String = "0"
var res: Double {
get {
//digits.hasSuffix(".") ? Double(digits.dropLast()) ?? 0.0 : Double(digits) ?? 0.0
digits.hasSuffix(".") ? Double(digits) ?? 0.0 : Double(digits) ?? 0.0
}
nonmutating set {
digits = String(format: "%.10g", newValue) //<- May need better formatting
}
}
var body: some View {
VStack{
Spacer()
HStack{
Spacer()
Text("\(digits)")
.font(.system(size: 50))
.bold()
.padding()
}
Spacer()
LazyVGrid(columns: gridItemLayout, content: {
ForEach(0..<5){ i in
ForEach(0..<4){ j in
RoundedRectangle(cornerRadius: 35.0)
.foregroundColor(.orange)
.frame(width: 80, height: 80, alignment: .center)
.overlay(
Text("\(numeri[i][j].rawValue)")
.font(.largeTitle)
.foregroundColor(.black)
).onTapGesture {
switch numeri[i][j] {
case Nums.AC:
operat = Nums.AC;
res = 0
case Nums.uguale:
operat = Nums.uguale;
res = final
case Nums.somma:
operat = Nums.somma;
previousVar = res;
res = 0;
con = 0
case Nums.meno:
operat = Nums.meno;
previousVar = res;
res = 0
con = 0
case Nums.divisione:
operat = Nums.divisione;
previousVar = res;
res = 0;
con = 0
case Nums.moltiplicazione:
operat = Nums.moltiplicazione;
previousVar = res;
res = 0;
con = 0
case Nums.percentuale:
operat = Nums.percentuale;
res = res / 100
case Nums.piùMeno:
operat = Nums.piùMeno;
if digits.hasPrefix("-") {
digits = String(digits.dropFirst())
} else {
digits = "-" + digits
}
con = 0
case Nums.virgola:
operat = Nums.virgola;
if !digits.contains(".") {
digits += "."
}
default:
if digits == "0" {
digits = numeri[i][j].rawValue
} else {
digits += numeri[i][j].rawValue
}
con += 1
}
}
}
}
}).onReceive(timer) { _ in
if con != 0 {
if operat == Nums.divisione{
final = previousVar / res
} else if operat == Nums.meno{
final = previousVar - res
} else if operat == Nums.moltiplicazione{
final = previousVar * res
} else if operat == Nums.somma{
final = previousVar + res
}
}
}
}.padding(2)
}
}

Maybe at line 51 and 52 or 121
(If you can explain my mistakes all around the code I would be grateful)
Thank you
Answered by OOPer in 668596022

But it doesn't work when decimal in the second operand.

Try 0.1 + 0.2, you won't get the right result (at least for me)

Thanks, all.

Please try commenting out line 122:
Code Block
                                    //operat = Nums.virgola;


Do you know why the comma in this calculator app isn't working:

I cannot find any commas (,) in your code.
Are you calling the decimal point (.) as comma?

And isn't working is the worst phrase to tell what is happening.

Can you tell?
  • The steps to reproduce the issue (in detail, one by one)

  • What actually happens?

  • What you expect?

You have defined virgola as dot.
Code Block
case virgola = "."

Is it intentional ?

May be you should define:

Code Block
case virgola = ","
case punto = "."

and add punto to numeri

However, I tested your code, it seems to work.
How do you enter comma ?
So, when I press the decimal point button it should add a decimal point, what happens is that when I press the decimal point it doesn't consider the numbers that I write after the decimal point.
Sorry for my inaccuracy, I'm still learning and thank you very much
it doesn't consider the numbers that I write after the decimal point.
I tapped:
8
.
5
X
2


and get 17.
All works. Except that it displays 0 when tapping X.

But it doesn't work when decimal in the second operand.
Thanks for your reply.

I have tried your code as exactly the same as shown in the opening post of this thread.

when I press the decimal point button it should add a decimal point,

  • Run the app

=> 0 shown
  • Press the decimal point

=> 0. is shown (a decimal point is actually added)

what happens is that when I press the decimal point it doesn't consider the numbers that I write after the decimal point.

(Continuing)
  • Press 2

=> 0.2 is shown
  • Press X

=> 0 is shown
  • Press 5

=> 5 is shown
  • Press =

=> 1 is shown

So, the calculation is made considering the number after the decimal point.

Did you get some different results than this?
Try 0.1 + 0.2, you won't get the right result (at least for me)

Did you get some different results than this?

No
Accepted Answer

But it doesn't work when decimal in the second operand.

Try 0.1 + 0.2, you won't get the right result (at least for me)

Thanks, all.

Please try commenting out line 122:
Code Block
                                    //operat = Nums.virgola;


I instrumented your code and there is a design flaw:

Code Block
var body: some View {
VStack{
Spacer()
HStack{
Spacer()
Text("\(digits)")
.font(.system(size: 50))
.bold()
.padding()
}
Spacer()
LazyVGrid(columns: gridItemLayout, content: {
ForEach(0..<5){ i in
ForEach(0..<4){ j in
RoundedRectangle(cornerRadius: 35.0)
.foregroundColor(.orange)
.frame(width: 80, height: 80, alignment: .center)
.overlay(
Text("\(numeri[i][j].rawValue)")
.font(.largeTitle)
.foregroundColor(.black)
).onTapGesture {
switch numeri[i][j] {
case Nums.AC:
operat = Nums.AC;
res = 0
case Nums.uguale:
operat = Nums.uguale;
res = final
print("uguale", "final", final, "digits", digits)
case Nums.somma:
operat = Nums.somma;
previousVar = res;
res = 0;
con = 0
print("somma", "previousVar", previousVar, "digits", digits)
case Nums.meno:
operat = Nums.meno;
previousVar = res;
res = 0
con = 0
case Nums.divisione:
operat = Nums.divisione;
previousVar = res;
res = 0;
con = 0
case Nums.moltiplicazione:
operat = Nums.moltiplicazione;
previousVar = res;
res = 0;
con = 0
case Nums.percentuale:
operat = Nums.percentuale;
res = res / 100
case Nums.piùMeno:
operat = Nums.piùMeno;
if digits.hasPrefix("-") {
digits = String(digits.dropFirst())
} else {
digits = "-" + digits
}
con = 0
case Nums.virgola:
operat = Nums.virgola;
print("res", res, "con", con, "digits", digits)
if !digits.contains(".") {
digits += "."
}
default:
if digits == "0" {
digits = numeri[i][j].rawValue
} else {
digits += numeri[i][j].rawValue
}
con += 1
print("default res", res, "con", con, "digits", digits)
}
}
}
}
}).onReceive(timer) { _ in
if con != 0 {
if operat == Nums.divisione{
final = previousVar / res
} else if operat == Nums.meno{
final = previousVar - res
} else if operat == Nums.moltiplicazione{
final = previousVar * res
} else if operat == Nums.somma{
final = previousVar + res
print("final", final, "res", res, "previous", previousVar, "digits", digits)
}
}


I type : 3.8 + 2.1 =

I get:
default res 3.0 con 1 digits 3
res 3.0 con 1 digits 3
default res 3.8 con 2 digits 3.8
somma previousVar 3.8 digits 0
default res 2.0 con 1 digits 2
final 5.8 res 2.0 previous 3.8 digits 2

… this line repeated because of timer

final 5.8 res 2.0 previous 3.8 digits 2
res 2.0 con 1 digits 2
default res 2.1 con 2 digits 2.1
uguale final 5.8 digits 5.8

This shows that the computation:
Code Block
final = previousVar + res
print("final", final, "res", res, "previous", previousVar, "digits", digits)

is done before the second operand with the decimal is completely read into res: it is read after the computation.

Note: with the names of your var (what is con ?) it is extremely difficult to grasp your code.
Why don't you save the 2 operands and just compute (as you would do with a reverse polish notation) ?
@@OOPer: that does it.

It was clearing the operator. But kept the first operand.
Comma not working
 
 
Q