locked
Modulus Operator

    Question

  • I am trying to learn how to use the modulus operator.

     

    this excersise is a change calculator and is supposed to calculate the number of dollars , qtrs, dimes, nickels and pennies from the change that is calculated. 

    in the form if i put a value in for owed = 30.00

    and paid 34.25

    my dollars returned = 4 and that is correct but the number of qtrs = 0 and should be 1.

    I am not sure how to correctly use this - any assistance you can provide is great - this is purely educational

        Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalc.Click
            Dim owed As Decimal
            Dim paid As Decimal
            Dim change As Decimal
            Const dollars As Decimal = 1
            Const quarters As Double = 0.25
            Const dimes As Decimal = 0.1
            Const nickels As Decimal = 0.05
            Const pennies As Decimal = 0.01
            Dim remdollars As Decimal
            Dim remquarters As Decimal
            Dim remdimes As Decimal
            Dim remnickels As Decimal
            Dim rempennies As Decimal
    
            ' gather user input 
            Decimal.TryParse(txtAmtOwed.Text, owed)
            Decimal.TryParse(txtAmtPaid.Text, paid)
    
            ' perform calculations
            change = paid - owed
            remdollars = change \ dollars
            remquarters = change Mod quarters
    
    
            ' display results
            txtChange.Text = change.ToString("C2")
            txtDollars.Text = remdollars.ToString()
            txtQtr.Text = remquarters.ToString
    
    
    
    
        End Sub
    End Class
    


    KDW
    Friday, September 16, 2011 5:03 AM

Answers

  • food for thought:

    first, after finding out how many dollars are in the change, don't you need to subtract that from the change? You would need to do that after each denomination, by the way

    second, if you are using the   \   operator to find remdollars, doesn't it make sense to use that same operator to find the remquarters?


    Mod returns the remainder, and since 4.25 can be divided evenly by 0.25 ( = 17 by the way), 4.25 Mod 0.25 returns 0

    However, 4.30 Mod 0.25 (which equals 17.2) would return 0.05


    Friday, September 16, 2011 7:01 AM
  • First of all don't work in dollars, work in cents. Floating point types are slow, large and sometimes imprecise. For this problem you are interested in using integer division so you don't want floating point types anyway! You could just use integer.

    Secondly it is a recursive problem:

    You have to find which is the largest coin or note that fits into x, the remainder becomes the new x.

    So in the uk we have notes and coins with denominations from, say, £20 to 1p: 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1

    If I am to give change of £99.99 then I start off with:

    1) What's the largest note that fits into 9999? Well it's the 2000.
    2) How many times does it fit into 9999? Well it fits 9999 \ 2000 times = 4 times. So we need 4 £20 notes.
    3) How much change is left? Answer: 1999

    Now we start again at (1) using 1999 as input. If there was 0 remaining then we would know we were done. If you get it working then you could try tweaking it a bit. The second time through you wouldn't need to test £20 because you already have - so you could start at £10 - this would trim off some cpu instructions (yeah, ok, it doesn't really matter because computers are rather quick nowadays). Or, you could try using the Math.DivRem function to do the division and get the remainder in one call...

    Now I want to show some amazing code, but that would be cheating.

    Saturday, September 17, 2011 1:13 AM
  • Hi siera_gld,

     

    Try the following code please.

    I have two TextBoxes called,

    txtCostAmt

    txtAmtPaid

    for the Cost Amount and the Amount Paid respectively.

     

    Then for the output I have:>>

     

            'Display results
            txtChange.Text = change.ToString("C2") ' Shows the total change.
            txtDollars.Text = remdollars.ToString 'Shows number of Dollars.
            txtQuarters.Text = remquarters.ToString 'Shows the number of Quarters.
            txtDimes.Text = remdimes.ToString 'Shows the number of Dimes.
            txtNickels.Text = remnickels.ToString 'Shows the number of Nickels.
            txtPennies.Text = rempennies.ToString 'Shows the number of Pennies.
    

     

     

    Here is the total code:>>

     

    Option Strict Off
    Option Explicit On
    Option Infer Off
    
    Public Class Form1
    
        Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalc.Click
    
            Dim cost As Decimal
            Dim paid As Decimal
            Dim change As Decimal
            Dim tempChange As Decimal
            Const dollars As Decimal = 1
            Const quarters As Double = 0.25
            Const dimes As Decimal = 0.1D
            Const nickels As Decimal = 0.05D
            Const pennies As Decimal = 0.01D
            Dim remdollars As Decimal
            Dim remquarters As Decimal
            Dim remdimes As Decimal
            Dim remnickels As Decimal
            Dim rempennies As Decimal
    
            'Gather user input 
            Decimal.TryParse(txtCostAmt.Text, cost)
            Decimal.TryParse(txtAmtPaid.Text, paid)
    
            'Perform calculations
            change = paid - cost
            remdollars = Int(change / dollars)
            tempChange = change - remdollars
            remquarters = Int(tempChange / quarters)
            tempChange = tempChange - (remquarters * quarters)
            remdimes = Int(tempChange / dimes)
            tempChange = tempChange - (remdimes * dimes)
            remnickels = Int(tempChange / nickels)
            tempChange = tempChange - (remnickels * nickels)
            rempennies = Int(tempChange / pennies)
    
            'Display results
            txtChange.Text = change.ToString("C2") ' Shows the total change.
            txtDollars.Text = remdollars.ToString 'Shows number of Dollars.
            txtQuarters.Text = remquarters.ToString 'Shows the number of Quarters.
            txtDimes.Text = remdimes.ToString 'Shows the number of Dimes.
            txtNickels.Text = remnickels.ToString 'Shows the number of Nickels.
            txtPennies.Text = rempennies.ToString 'Shows the number of Pennies.
    
        End Sub
    
    End Class
    

     


    I tested it by trying:>>

    24.07 for the cost.

    30.00 paid.

    Change is

    5.93

    comprising

    5 dollars

    3 quarters for 0.75

    1 dime for 0.10

    1 nickel for 0.05

    3 pennies for 0.03

    so 0.75 + 0.10 + 0.05 + 0.03 = 0.93

     




    Regards,

    profile for John Anthony Oliver at Stack Overflow, Q&A for professional and enthusiast programmers

    Click this link to see the NEW way of how to insert a picture into a forum post.

    Installing VB6 on Windows 7

    App Hub for Windows Phone & XBOX 360 developers.

    Sunday, September 18, 2011 1:02 AM

All replies

  • food for thought:

    first, after finding out how many dollars are in the change, don't you need to subtract that from the change? You would need to do that after each denomination, by the way

    second, if you are using the   \   operator to find remdollars, doesn't it make sense to use that same operator to find the remquarters?


    Mod returns the remainder, and since 4.25 can be divided evenly by 0.25 ( = 17 by the way), 4.25 Mod 0.25 returns 0

    However, 4.30 Mod 0.25 (which equals 17.2) would return 0.05


    Friday, September 16, 2011 7:01 AM
  • First of all don't work in dollars, work in cents. Floating point types are slow, large and sometimes imprecise. For this problem you are interested in using integer division so you don't want floating point types anyway! You could just use integer.

    Secondly it is a recursive problem:

    You have to find which is the largest coin or note that fits into x, the remainder becomes the new x.

    So in the uk we have notes and coins with denominations from, say, £20 to 1p: 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1

    If I am to give change of £99.99 then I start off with:

    1) What's the largest note that fits into 9999? Well it's the 2000.
    2) How many times does it fit into 9999? Well it fits 9999 \ 2000 times = 4 times. So we need 4 £20 notes.
    3) How much change is left? Answer: 1999

    Now we start again at (1) using 1999 as input. If there was 0 remaining then we would know we were done. If you get it working then you could try tweaking it a bit. The second time through you wouldn't need to test £20 because you already have - so you could start at £10 - this would trim off some cpu instructions (yeah, ok, it doesn't really matter because computers are rather quick nowadays). Or, you could try using the Math.DivRem function to do the division and get the remainder in one call...

    Now I want to show some amazing code, but that would be cheating.

    Saturday, September 17, 2011 1:13 AM
  • jo - you understand it -

     

    but some more nuggets of info would be good -

    I'm not quite sure how to write the remaining into a new variable or how to calculate the remaining for each currency

     


    KDW
    Saturday, September 17, 2011 5:02 PM
  • jo - you understand it -

     

    but some more nuggets of info would be good -

    I'm not quite sure how to write the remaining into a new variable or how to calculate the remaining for each currency

     


    KDW


    first, I agree with joOls about the concept of working in cents. That is how I did it a long time ago - it is much easier to work with Integers than decimals.

    How to do that? After you calculate the change,you multiply by 100. Then for the currency you do the same; so instead of a quarter = 0.25, it equals 25.

    After you calculate how many dollars it takes, you would need to multiply the # dollars x 100 to get how many cents in that many dollars, and finally subtract that from the change to get the remaining change.

    change = paid - owed
            remdollars = change \ dollars
    'code here to subtract cents in # dollars from change
    change = change - (cents in dollars)
            remquarters = change \ quarters
    


    and continue on through all the coins.

    One way to check all the coins is to use a collection. In this case a Dictionary (of Integer,String) would work because the Key could be the value of the Item (for a quarter it would = 25) and the Value could be the coin name (Quarter). Don't you need to know which coin you are working with to keep track of how many quarters, dimes, etc? Iterate through all the pairs in the dictionary, passing them one by one to a function to do the calculations.

    It might sound confusing or difficult, but once you figure out what to do for the dollars, the rest will follow the same format - that is why you would want to use a Function -so you don't have to write the code to do the same calculations a few times.

    Saturday, September 17, 2011 7:33 PM
  • Hi siera_gld,

     

    Try the following code please.

    I have two TextBoxes called,

    txtCostAmt

    txtAmtPaid

    for the Cost Amount and the Amount Paid respectively.

     

    Then for the output I have:>>

     

            'Display results
            txtChange.Text = change.ToString("C2") ' Shows the total change.
            txtDollars.Text = remdollars.ToString 'Shows number of Dollars.
            txtQuarters.Text = remquarters.ToString 'Shows the number of Quarters.
            txtDimes.Text = remdimes.ToString 'Shows the number of Dimes.
            txtNickels.Text = remnickels.ToString 'Shows the number of Nickels.
            txtPennies.Text = rempennies.ToString 'Shows the number of Pennies.
    

     

     

    Here is the total code:>>

     

    Option Strict Off
    Option Explicit On
    Option Infer Off
    
    Public Class Form1
    
        Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalc.Click
    
            Dim cost As Decimal
            Dim paid As Decimal
            Dim change As Decimal
            Dim tempChange As Decimal
            Const dollars As Decimal = 1
            Const quarters As Double = 0.25
            Const dimes As Decimal = 0.1D
            Const nickels As Decimal = 0.05D
            Const pennies As Decimal = 0.01D
            Dim remdollars As Decimal
            Dim remquarters As Decimal
            Dim remdimes As Decimal
            Dim remnickels As Decimal
            Dim rempennies As Decimal
    
            'Gather user input 
            Decimal.TryParse(txtCostAmt.Text, cost)
            Decimal.TryParse(txtAmtPaid.Text, paid)
    
            'Perform calculations
            change = paid - cost
            remdollars = Int(change / dollars)
            tempChange = change - remdollars
            remquarters = Int(tempChange / quarters)
            tempChange = tempChange - (remquarters * quarters)
            remdimes = Int(tempChange / dimes)
            tempChange = tempChange - (remdimes * dimes)
            remnickels = Int(tempChange / nickels)
            tempChange = tempChange - (remnickels * nickels)
            rempennies = Int(tempChange / pennies)
    
            'Display results
            txtChange.Text = change.ToString("C2") ' Shows the total change.
            txtDollars.Text = remdollars.ToString 'Shows number of Dollars.
            txtQuarters.Text = remquarters.ToString 'Shows the number of Quarters.
            txtDimes.Text = remdimes.ToString 'Shows the number of Dimes.
            txtNickels.Text = remnickels.ToString 'Shows the number of Nickels.
            txtPennies.Text = rempennies.ToString 'Shows the number of Pennies.
    
        End Sub
    
    End Class
    

     


    I tested it by trying:>>

    24.07 for the cost.

    30.00 paid.

    Change is

    5.93

    comprising

    5 dollars

    3 quarters for 0.75

    1 dime for 0.10

    1 nickel for 0.05

    3 pennies for 0.03

    so 0.75 + 0.10 + 0.05 + 0.03 = 0.93

     




    Regards,

    profile for John Anthony Oliver at Stack Overflow, Q&A for professional and enthusiast programmers

    Click this link to see the NEW way of how to insert a picture into a forum post.

    Installing VB6 on Windows 7

    App Hub for Windows Phone & XBOX 360 developers.

    Sunday, September 18, 2011 1:02 AM
  • Thank you John -

    The recursive nature of the tempchange and the ability to use it multiple times within the same control button is something I have to wrap my head around.....

    :)


    KDW
    Monday, September 19, 2011 3:38 PM
  • Thank you John -

    The recursive nature of the tempchange and the ability to use it multiple times within the same control button is something I have to wrap my head around.....

    :)


    KDW


    now that this thread has been marked...

    if you like the recursive nature, take it a step further and write a Function as I mentioned above. If you notice the same calculation is done over and over, just the variables change:

    remdollars = Int(change / dollars)
            tempChange = change - remdollars
            remquarters = Int(tempChange / quarters)
            tempChange = tempChange - (remquarters * quarters)
            remdimes = Int(tempChange / dimes)
            tempChange = tempChange - (remdimes * dimes)
            remnickels = Int(tempChange / nickels)
            tempChange = tempChange - (remnickels * nickels)
            rempennies = Int(tempChange / pennies)
    
    
    

    in a case like this just write 1 function to perform the calculations and pass the variables to the function.

    as an example of this try this in an app with

    Dim dictCoins As New Dictionary(Of Integer, String)
        Dim sb As New StringBuilder
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            TextBox1.Text = "26.69"
            TextBox2.Text = "40.00"
    
            dictCoins.Add(2000, "Twenties")
            dictCoins.Add(1000, "Tens")
            dictCoins.Add(500, "Fives")
            dictCoins.Add(100, "Ones")
            dictCoins.Add(25, "Quarters")
            dictCoins.Add(10, "Dimes")
            dictCoins.Add(5, "Nickels")
            dictCoins.Add(1, "Pennies")
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
            Dim dblCost As Double
            Dim dblCash As Double
            Dim dblChange As Double
            Dim intChange As Integer
    
            If Not Double.TryParse(TextBox1.Text, dblCost) Then
                MessageBox.Show("enter a valid cost")
                Exit Sub
            End If
    
            If Not Double.TryParse(TextBox2.Text, dblCash) Then
                MessageBox.Show("enter a valid payment")
                Exit Sub
            End If
    
            dblChange = dblCash - dblCost
    
            If dblCost > dblCash Then
                MessageBox.Show("What do you think this is, a charity?" & _
                                vbCrLf & vbCrLf & "You owe " & Math.Abs(dblChange).ToString, _
                                "Balance Due", MessageBoxButtons.OK, MessageBoxIcon.Hand)
                Exit Sub
            End If
    
            sb.Append("Change due = " & dblChange.ToString("C") & vbCrLf)
            dblChange *= 100
            For Each kvp As KeyValuePair(Of Integer, String) In dictCoins
               
                dblChange = ChangeRemaining(dblChange, kvp)
            Next
    
            MessageBox.Show(sb.ToString)
    
        End Sub
    
        Private Function ChangeRemaining(ByVal chg As Double, ByVal kvp As KeyValuePair(Of Integer, String)) As Integer
            Dim coin As Integer = kvp.Key
            Dim numberCoins As Integer = CInt(Math.Floor(chg / coin))
            Dim changeLeft As Integer = CInt(chg)
    
            sb.Append(String.Format("{0} : {1}", kvp.Value, numberCoins) & vbCrLf)
    
            changeLeft -= (numberCoins * kvp.Key)
    
            Return changeLeft
        End Function

     

     

     

     

     

     

     


    • Edited by jwavila Tuesday, September 20, 2011 3:24 AM format code
    Monday, September 19, 2011 9:37 PM
  • Thank you John -

    The recursive nature of the tempchange and the ability to use it multiple times within the same control button is something I have to wrap my head around.....

    :)


    KDW

    Hi again siera_gld,

     

    It is quite easy really.

    Imagine you want to give change for at item that costs $24.07 from $30.00

    30.00 - 24.07 = 5.93

    Subtract whole dollars which is 5 dollars. We are left with 0.93

     

    Subtract whole quarters, we are left with 0.93 - ( 3 X 0.25 ) = 0.18

     

    Subtract whole dimes, 0.18 - 0.10 we are left with 0.08

     

    Subtract whole nickels, 0.08 - 0.05 = 0.03

    0.03 / 0.01 = 3 whole pennies.

     

    The code simply works in the above manner by subtracting whole dollars, then whole quarters,

    then whole dimes, then whole nickels to leave the pennies.

    The tempChange variable simply holds the value for the next step in the calculations.  :-D

     

    Think along the lines of what change do I still need to give to get to the required amount

    as if you were working on a check-out in a shop. I do this 5 ( sometimes 6 ) days a week at work.

    Except that when you look at loose change, you will give change from whatever coins are left as available.  :)

     




    Regards,

    profile for John Anthony Oliver at Stack Overflow, Q&A for professional and enthusiast programmers

    Click this link to see the NEW way of how to insert a picture into a forum post.

    Installing VB6 on Windows 7

    App Hub for Windows Phone & XBOX 360 developers.

    Monday, September 19, 2011 11:16 PM