Type Coercion and Math
Posted: Fri Feb 28, 2025 3:12 am
I'm trying to get back up to speed with PB and I'm running into something that is make me feel rather dumb.
I was trying to create a simple calculator. I just placed two StringGadgets and one ComboBox and one TextGadget in a window with the Forms Designer, along with a button that says "Calculate".
When the user enters 2 numbers in the StringGadgets and then selects and operator (+,-.*,/) and then clicks calculate, then I want to grab the values from the StringGadgets and perform the math and then write the result to the TextGadget like: "3 + 5 = 8".
Easy, right?
However, I also want the program to be able to do floating point math if the user doesn't enter simple integers into the StringGadgets and this is where I'm starring to pull what little hair I have left out of my head. I've been trying to figure out the simplest way to convert the strings retrieved by GetGadgetText to either an int or a double and then to perform the intended math and get results that make sense. Like if both numbers are integers I want to do integer math and have an integer result (unless it's division that results in a double). Or, if one of the numbers is not an integer, I want to perform the intended math and get a double as a result.
In the beginning, I had something as simple as this:
Which, of course only works for addition, subtraction, and multiplication of integers.
So, then I started coding myself in knots trying stuff like this:
Which, will not even compile and gives and error that "Variable already declared with another type: tResult." in relation to this line:
tResult.d = tOp1 + tOp2
Help. There has to be an easy way to do this, doesn't there?
I was trying to create a simple calculator. I just placed two StringGadgets and one ComboBox and one TextGadget in a window with the Forms Designer, along with a button that says "Calculate".
When the user enters 2 numbers in the StringGadgets and then selects and operator (+,-.*,/) and then clicks calculate, then I want to grab the values from the StringGadgets and perform the math and then write the result to the TextGadget like: "3 + 5 = 8".
Easy, right?
However, I also want the program to be able to do floating point math if the user doesn't enter simple integers into the StringGadgets and this is where I'm starring to pull what little hair I have left out of my head. I've been trying to figure out the simplest way to convert the strings retrieved by GetGadgetText to either an int or a double and then to perform the intended math and get results that make sense. Like if both numbers are integers I want to do integer math and have an integer result (unless it's division that results in a double). Or, if one of the numbers is not an integer, I want to perform the intended math and get a double as a result.
In the beginning, I had something as simple as this:
Code: Select all
Procedure doCalculation(x)
tResult$ = "No Calculation Performed"
tCalculated = #False
;MessageRequester("tCalculated", "tCalculated = " + Str(tCalculated))
tOp1 = Val(GetGadgetText(String_1))
tOp2 = Val(GetGadgetText(String_2))
tOper$ = GetGadgetText(Combo_0)
;MessageRequester("Currently Selected Operator", "The currently selected operator is: " + tOper$)
Select tOper$
Case "+"
tResult = tOp1 + tOp2
tCalculated = #True
Case "-"
tResult = tOp1 - tOp2
tCalculated = #True
Case "*"
tResult = tOp1 * tOp2
tCalculated = #True
Case "/"
tResult = tOp1 / tOp2
tCalculated = #True
Default
MessageRequester("Select an Operator", "You must first select an operator.")
EndSelect
;MessageRequester("tCalculated", "tCalculated = " + Str(tCalculated))
If tCalculated = #True
tResult$ = Str(tOp1) + " " + tOper$ + " " + Str(tOp2) + " = " + Str(tResult)
EndIf
SetGadgetText(Text_0, tResult$)
EndProcedure
So, then I started coding myself in knots trying stuff like this:
Code: Select all
Procedure doCalculation(x)
tResult$ = "No Calculation Performed"
tCalculated = #False
;MessageRequester("tCalculated", "tCalculated = " + Str(tCalculated))
tOp1$ = GetGadgetText(String_1)
If FindString(tOp1$, ".") > 0
;Debug "tOp1$ contains ."
tOp1.d = ValD(tOp1$)
tAllInts = #False
Else
Debug "tOp1$ doest NOT contain ."
tOp1 = Val(tOp1$)
EndIf
If TypeOf(tOp1) = #PB_Double
Debug "PB_Double"
Else
Debug "PB_Integer"
EndIf
tOp2$ = GetGadgetText(String_2)
If FindString(tOp2$, ".") > 0
tOp2.d = ValD(tOp2$)
tAllInts = #False
Else
tOp2 = Val(tOp2$)
EndIf
tOper$ = GetGadgetText(Combo_0)
;MessageRequester("Currently Selected Operator", "The currently selected operator is: " + tOper$)
Select tOper$
Case "+"
If tAllInts = #True
tResult = tOp1 + tOp2
Else
tResult.d = tOp1 + tOp2
EndIf
tCalculated = #True
Case "-"
If tAllInts = #True
tResult = tOp1 - tOp2
Else
tResult.d = tOp1 - tOp2
EndIf
tCalculated = #True
Case "*"
If tAllInts = #True
tResult = tOp1 * tOp2
Else
tResult.d = tOp1 * tOp2
EndIf
tCalculated = #True
Case "/"
tResult.d = tOp1 / tOp2
tCalculated = #True
Default
MessageRequester("Select an Operator", "You must first select an operator.")
EndSelect
;MessageRequester("tCalculated", "tCalculated = " + Str(tCalculated))
If tCalculated = #True
If TypeOf(tResult) = #PB_Double
tCalculation$ = StrD(tResult)
Else
tCalculation$ = Str(tResult)
EndIf
tResult$ = tOp1$ + " " + tOper$ + " " + tOp2$ + " = " + tCalculation$
EndIf
SetGadgetText(Text_0, tResult$)
EndProcedure
Procedure doReset(x)
SetGadgetText(String_1, "")
SetGadgetText(String_2, "")
SetGadgetText(Text_0, "")
EndProcedure
tResult.d = tOp1 + tOp2
Help. There has to be an easy way to do this, doesn't there?