Question How can I add two decimals?

audio_uphoria

Active member
Joined
Jan 28, 2009
Messages
31
Programming Experience
Beginner
Hello, for some reason I can't get this to work. I am making an app that will let the user put in the amount of pounds of coffee they want to order and they can order either regular or decaf. Each one has its own dim variable and is calculated after the click event of the calc button. I want to be able to add decimals if the user would want lets say 1.5lbs of regular and 2.3 lbs of decaf. Here is my non working code.... as you can see I tried to convert the text into decimal using try parse but when I run the program and enter whole numbers it works fine, when I enter 1.8 for reg and 5.3 for decaf for example all my output is zero. Please, enlighten me.
VB.NET:
' Declare Variables
        Const tax As Decimal = 0.065D
        Const regularPrice As Decimal = 6.99D
        Const decafPrice As Decimal = 5.99D
        Dim regular As Decimal
        Dim decaf As Decimal
        Dim isConverted As Boolean
        Dim totalPound As Integer
        Dim totalPrice As Decimal
        Dim priceBefore As Decimal
        Dim CurrentTax As Decimal

        ' Convert input
        isConverted = Decimal.TryParse(txtRegular.Text, _
        NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo, regular)
        isConverted = Decimal.TryParse(txtDecaf.Text, _
        NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo, decaf)


        ' Calculate (in order) Pounds, Price before, Tax, and Total Price
        totalPound = CInt(regular + decaf)
        ' If order exceeds 1000lbs in any combination of coffee ordered then message states more than 1000lbs unavailable
        If totalPound > 1000 Then
            MessageBox.Show("I'm sorry, our warehouse does not currently stock no more than 500lbs of either type of coffee.")

            lblTotalPounds.Text = ""
            lblPriceBefore.Text = ""
            lblTax.Text = ""
            lblTotal.Text = ""
            txtRegular.Focus()
        End If

        priceBefore = CDec((regular * regularPrice) + (decaf * decafPrice))
        CurrentTax = priceBefore * tax
        totalPrice = CurrentTax + priceBefore

        ' Dispplay Calculated Results
        lblTotalPounds.Text = Convert.ToString(totalPound)
        lblPriceBefore.Text = priceBefore.ToString("C")
        lblTax.Text = CurrentTax.ToString("C")
        lblTotal.Text = totalPrice.ToString("C")

    End Sub
Sorry for it being long just wanted to make sure I didn't omit any important info
 
First up, why are you assigning the result of TryParse to the isConverted variable and then simply ignoring it? The whole point is that the result of TryParse tells you whether the conversion was successful or not. Surely if it's not you want to notify the user of that.

As for the question, you are EXPLICITLY telling the TryParse method that the only formatting that's allowed is thousand separators. That means that decimal separators are NOT allowed. Why do you need to specify any specific formatting at all? Just use the overload of TryParse with two parameters.

Also, while it won't hurt, why do you need to convert a Decimal to a Decimal?
VB.NET:
priceBefore = CDec((regular * regularPrice) + (decaf * decafPrice))
All four values on the right are Decimal so the result is Decimal. CDec is pointless.

What you should be doing is something like this:
VB.NET:
If Decimal.TryParse(txtRegular.Text, regular) AndAlso _
   Decimal.TryParse(txtDecaf.Text, decaf) Then
    'Perform calculation here.
Else
    'Notify user of error here.
End If
Note that that will require the user to enter "0" if they don't want any of either type. If you want to allow them to leave a field blank then you'll have to test for empty strings explicitly.
 
I guess I was under the assumption that the isconverted is for the purpose of converting string to a number value. Well I see what your saying and coded it like this and I'm still getting errors now whether I put in whole numbers OR decimals so I decided to also convert everything to a single because thats what I really want now I get this. And I will get the error message so it's not doing the math....

VB.NET:
Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalc.Click

        ' Declare Variables
        Const tax As Single = 0.065D
        Const regularPrice As Single = 6.99
        Const decafPrice As Single = 5.99
        Dim regular As Single
        Dim decaf As Single
        Dim isConverted As Boolean
        Dim totalPound As Integer
        Dim totalPrice As Single
        Dim priceBefore As Single
        Dim CurrentTax As Single


        ' Convert input
        If isConverted = Single.TryParse(txtRegular.Text, regular) AndAlso _
            isConverted = Single.TryParse(txtDecaf.Text, decaf) Then
            ' Calculate (in order) Pounds, Price before, Tax, and Total Price
            totalPound = CInt(regular + decaf)
            priceBefore = (regular * regularPrice) + (decaf * decafPrice)
            CurrentTax = priceBefore * tax
            totalPrice = CurrentTax + priceBefore
        Else
            MessageBox.Show("error")
        End If
        ' Dispplay Calculated Results
        lblTotalPounds.Text = totalPound.ToString
        lblPriceBefore.Text = priceBefore.ToString("C")
        lblTax.Text = CurrentTax.ToString("C")
        lblTotal.Text = totalPrice.ToString("C")

        ' If order exceeds 1000lbs in any combination of coffee ordered then message states more than 1000lbs unavailable
        If totalPound > 1000 Then

            MessageBox.Show("I'm sorry, our warehouse does not currently stock no more than 500lbs of either type of coffee", "Exceeded Available Amount", _
            MessageBoxButtons.OK, MessageBoxIcon.Information)
            lblTotalPounds.Text = ""
            lblPriceBefore.Text = ""
            lblTax.Text = ""
            lblTotal.Text = ""
            txtRegular.Focus()
        End If
        If totalPound < 1 Then
            MessageBox.Show("Sorry, at this time you cannot order no less than 1 lb of coffee", "Invalid Entry", _
            MessageBoxButtons.OK, MessageBoxIcon.Information)
            lblTotalPounds.Text = ""
            lblPriceBefore.Text = ""
            lblTax.Text = ""
            lblTotal.Text = ""
            txtRegular.Focus()
        End If

    End Sub
 
OK I think I got it! I'm so close! The only problem now is lbltotalpound isnt displaying the decimal if I order 1.5 or reg and 1 of decaf it will display only two. If I add 1.5 reg and 1.5 decaf it will display three. Now, in the first example 1.5 reg and 1 decaf even though total pound only shows 2 and not the 2.5 like it should the other labels are doing the math as if I order 2.5lbs total. All I need to do is figure out how to make lbltotal pound display what I'm actually ordering heres my new and improved code, any ideas?

VB.NET:
Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalc.Click

        ' Declare Variables
        Const tax As Single = 0.065D
        Const regularPrice As Single = 6.99
        Const decafPrice As Single = 5.99
        Dim regular As Single
        Dim decaf As Single

        Dim totalPound As Integer
        Dim totalPrice As Single
        Dim priceBefore As Single
        Dim CurrentTax As Single


        ' Convert input
        Single.TryParse(txtRegular.Text, regular)
        Single.TryParse(txtDecaf.Text, decaf)
        ' Calculate (in order) Pounds, Price before, Tax, and Total Price
        totalPound = CInt(regular + decaf)
        priceBefore = (regular * regularPrice) + (decaf * decafPrice)
        CurrentTax = priceBefore * tax
        totalPrice = CurrentTax + priceBefore

        ' Dispplay Calculated Results
        lblTotalPounds.Text = totalPound.ToString
        lblPriceBefore.Text = priceBefore.ToString("C")
        lblTax.Text = CurrentTax.ToString("C")
        lblTotal.Text = totalPrice.ToString("C")

        ' If order exceeds 1000lbs in any combination of coffee ordered then message states more than 1000lbs unavailable
        If totalPound > 1000 Then

            MessageBox.Show("I'm sorry, our warehouse does not currently stock no more than 500lbs of either type of coffee", "Exceeded Available Amount", _
            MessageBoxButtons.OK, MessageBoxIcon.Information)
            lblTotalPounds.Text = ""
            lblPriceBefore.Text = ""
            lblTax.Text = ""
            lblTotal.Text = ""
            txtRegular.Focus()
        End If
        If totalPound < 1 Then
            MessageBox.Show("Sorry, at this time you cannot order no less than 1 lb of coffee", "Invalid Entry", _
            MessageBoxButtons.OK, MessageBoxIcon.Information)
            lblTotalPounds.Text = ""
            lblPriceBefore.Text = ""
            lblTax.Text = ""
            lblTotal.Text = ""
            txtRegular.Focus()
        End If

    End Sub
 
You're still not using the result of TryParse. I would think you would want to notify the user if they enter invalid data rather than just silently using zero.

Also, you should have stuck with Decimal. Single and Double are floating-point types and susceptible to round-off errors. You should ALWAYS use Decimal for financial calculations. Also, if you were going to use Single then you shouldn't be assigning a Decimal literal to a Single constant:
VB.NET:
Const tax As Single = 0.065D
The "D" is for Decimal. For single it should be "F" for "float".

As for your issue, you've got totalPound declared as Integer, which can only be a whole number. You can't expect to display a fractional number using a type that is incapable of holding fractions. All your numbers are implicitly rounded to the nearest whole so that they can be stored in an Integer variable.
 
Back
Top