11 Replies - 757 Views - Last Post: 12 July 2012 - 02:52 PM Rate Topic: -----

#1 CodingInBoise  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 25
  • Joined: 16-June 12

Odd behavior in change calculator

Posted 11 July 2012 - 01:39 PM

I have experienced some odd behavior while creating a change calculator. I believe I know how to fix it, but I don't understand why the program behaved the way it did to begin with.
I have inserted several WriteLine statements to assist with debugging. The values I get are confusing. To test the program and get the error I have received, use the value 93. Other values that cause problems include 13, and 53.
I would like to better understand the nature of this error, and am not so much looking for a solution for fixing it, although that could prove useful as well.
Here is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Chapter3Excercise6
{
    class ChangeForDollar
    {
        public static double changeDouble = -999;  //made global to allow access from all methods

        static void Main()
        {
            AmountMethod();
            double qQ = QuarterMethod();
            double dQ = DimeMethod();
            double nQ = NickelMethod();
            double pQ = PennyMethod();

            //output data
            Console.WriteLine("You will recive " + qQ + " quarter(s).");
            Console.WriteLine("You will recive " + dQ + " dimes(s).");
            Console.WriteLine("You will recive " + nQ + " nickels(s).");
            if (pQ > 1)
            {
                Console.WriteLine("You will recive " + pQ + " pennies.");
            }
            else
            {
                Console.WriteLine("You will recive " + pQ + " penny.");
            }
        }//end of main
        static void AmountMethod()  //Brings in data
        {
            Console.WriteLine("How much did you spend today? Please enter a value that is less than a dollar");
            String valueString = Console.ReadLine();
            double valueDouble = double.Parse(valueString);

            if (valueDouble >= 1)//allows user to input price in either $x.xx format or xx¢
            {
                valueDouble = (valueDouble / 100);
            }

            changeDouble = (1.00 - valueDouble);
            Console.WriteLine("\nValue of changeDouble at end of AmountMethod() is: " + changeDouble + "\n");
        }
        static int QuarterMethod()
        {
            int quarterQ = 0;

            while (changeDouble >= .25)
            {
                ++quarterQ;
                changeDouble = (changeDouble - .25);
                Console.WriteLine("Value of changeDouble at end of while loop\n in QuarterMethod() is: " + changeDouble + "\n");
            }
            return quarterQ;
        }
        static int DimeMethod()
        {
            int dimeQ = 0;

            while (changeDouble >= .10)
            {
                ++dimeQ;
                changeDouble = (changeDouble - .10);
                Console.WriteLine("Value of changeDouble at end of while loop\n in DimeMethod() is: " + changeDouble + "\n");
            }
            return dimeQ;
        }
        static int NickelMethod()
        {
            int nickelQ = 0;

            while (changeDouble >= .05)
            {
                ++nickelQ;
                changeDouble = (changeDouble - .05);
                Console.WriteLine("Value of changeDouble at end of while loop\n in NickelMethod() is: " + changeDouble + "\n");
            }
            return nickelQ;
        }
        static int PennyMethod()
        {
            int pennyQ = 0;
            Console.WriteLine("Value of changeDouble at start of PennyMethod() is: " + changeDouble + "\n");
            while (changeDouble >= .01)
            {
                Console.WriteLine("Value of changeDouble inside while loop\n at start of loop in PennyMethod() is: " + changeDouble + "\n");
                ++pennyQ;
                Console.WriteLine("Value of changeDouble inside while loop\n before subtracting .01 in PennyMethod() is: " + changeDouble + "\n");
                changeDouble = (changeDouble - .01);
                Console.WriteLine("Value of changeDouble inside while loop\n after subtracting .01 in PennyMethod() is: " + changeDouble + "\n");
            }
            return pennyQ;
        }
    }//end of class
}//end of namespace



Thank you in advance for any comments, suggestions, and/or explanations.

Is This A Good Question/Topic? 0
  • +

Replies To: Odd behavior in change calculator

#2 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2216
  • View blog
  • Posts: 9,352
  • Joined: 29-May 08

Re: Odd behavior in change calculator

Posted 11 July 2012 - 01:56 PM

How to Debug Tutorial
Was This Post Helpful? 0
  • +
  • -

#3 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5316
  • View blog
  • Posts: 11,360
  • Joined: 02-June 10

Re: Odd behavior in change calculator

Posted 11 July 2012 - 01:59 PM

How can you tell what its doing when it closes immediatley?
Add a Console.ReadLIne to the end of the display so the user has to press enter before it closes.

Are you going out of your way to make things hard on yourself?
            double qQ = QuarterMethod();
            double dQ = DimeMethod();
            double nQ = NickelMethod();
            double pQ = PennyMethod();

This isn't 8th grade algebra: You can use meaningful names:
QuantityPennies
QuantityNickles
QuantityDimes
QuanityQuarters


personally I would avoid the while loops. Just use the modulus operator.
93 % 25 = 3 remainder 17
17 % 10 = 1 remainder 7
7 % 5 = 1 remainder 3
Done

Attached image(s)

  • Attached Image

Was This Post Helpful? 0
  • +
  • -

#4 ThrowsException  Icon User is offline

  • D.I.C Head

Reputation: 33
  • View blog
  • Posts: 83
  • Joined: 21-February 12

Re: Odd behavior in change calculator

Posted 11 July 2012 - 01:59 PM

What you are seeing is rounding errors as a result of using type double. For monetary values msdn encourages the use of Decimal
Was This Post Helpful? 2
  • +
  • -

#5 Tim.Simon  Icon User is offline

  • New D.I.C Head

Reputation: 13
  • View blog
  • Posts: 26
  • Joined: 12-June 12

Re: Odd behavior in change calculator

Posted 11 July 2012 - 02:15 PM

Rounding errors can occur when working with double and float variable types. To find out why this happens, see this article: http://docs.oracle.c...g_goldberg.html
Was This Post Helpful? 3
  • +
  • -

#6 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5316
  • View blog
  • Posts: 11,360
  • Joined: 02-June 10

Re: Odd behavior in change calculator

Posted 11 July 2012 - 03:49 PM

I'm really against just handing out working code especially for school work - but there is an exception for every rule.

I honestly think you gave this a good effort but could use some help with some better techniques.

Spoiler

Was This Post Helpful? 2
  • +
  • -

#7 CodingInBoise  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 25
  • Joined: 16-June 12

Re: Odd behavior in change calculator

Posted 12 July 2012 - 01:05 PM

First, thank you all for responding. After looking at your responses, I realized that I was not very clear about something.

I would like to know WHY this behaves how it does, not how to fix it.

This is a homework assignment, although it is not mine. I am a tutor at my local college. I have already taken the class that this assignment is for, and done quite well. However, the teacher that is teaching this class this time is using a different book, so I am not 100% familiar with all of the nuances of some of these exercises.
This code was written by a student I am helping, and many of the naming conventions he used are not what I would have used. That said, I also told him that naming conventions were up to him to decide what his standards were going to be. I made recommendations, but not all of them were implemented in this version of the code. He has said he would use better names in the future, but it would take too much needless effort to change the names for a simple homework assignment at that point.
As for why some of the things were done in ways that were more difficult than they needed to be, at least some of them were done that way to fulfill the requirements of the assignment.
The suggestion to use modulus was a great solution. I did not think of that. Thank you!

Quote

What you are seeing is rounding errors as a result of using type double. For monetary values msdn encourages the use of Decimal


I am not clear about why using a decimal would be more helpful. I understand that it is more accurate, but in this case I would have thought it would just put more 9s to the right of the decimal place. If I am wrong, please explain why.

Thank you all again for your responses. Those that I have found to be particularly helpful I have +1'd.
Was This Post Helpful? 0
  • +
  • -

#8 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5316
  • View blog
  • Posts: 11,360
  • Joined: 02-June 10

Re: Odd behavior in change calculator

Posted 12 July 2012 - 01:11 PM

View PostCodingInBoise, on 12 July 2012 - 02:05 PM, said:

I would like to know WHY this behaves how it does, not how to fix it.


Because the logic of your code is fraked up. We tried to dance around it by pointing you in other directions and not come out and stomp on your feelings. I guess 'subtle' didn't work this time.

View PostCodingInBoise, on 12 July 2012 - 02:05 PM, said:

I am not clear about why using a decimal would be more helpful. I understand that it is more accurate, but in this case I would have thought it would just put more 9s to the right of the decimal place. If I am wrong, please explain why.


As already stated double is prone to rounding errors - it rounds up and down differently than expected - it produces results other than what you would expect.
Was This Post Helpful? 1
  • +
  • -

#9 Curtis Rutland  Icon User is online

  • (╯°□°)╯︵ (~ .o.)~
  • member icon


Reputation: 4312
  • View blog
  • Posts: 7,467
  • Joined: 08-June 10

Re: Odd behavior in change calculator

Posted 12 July 2012 - 01:43 PM

To be a bit more specific, it's because double and decimal are fundamentally different.

http://stackoverflow...tead-of-decimal

http://csharpindepth...al/Decimal.aspx

Quote

The decimal type is just another form of floating point number - but unlike float and double, the base used is 10. If you haven't read the article linked above, now would be a good time to read it - I won't go into the basics of floating point numbers in this article.


Since it uses base 10 representations of the number involved, it's not prone to the rounding errors that binary-based floating point operations are. Of course, it's slower and takes more memory, but it's very important to use when representing anything with money, or anything that needs to be accurate with base 10 operations.
Was This Post Helpful? 3
  • +
  • -

#10 Tim.Simon  Icon User is offline

  • New D.I.C Head

Reputation: 13
  • View blog
  • Posts: 26
  • Joined: 12-June 12

Re: Odd behavior in change calculator

Posted 12 July 2012 - 02:08 PM

The article I posted previously goes into an in-depth mathematical explanation of why this happens. Another good link for a slightly simpler explanation would be here: http://csharpindepth...atingPoint.aspx

The reason for the error has to do with how doubles and floats are stored as binary. They sacrifice some accuracy for being able to work with larger or smaller numbers. As stated above, decimal gives up some of its flexibility so it can focus on accuracy.
Was This Post Helpful? 3
  • +
  • -

#11 CodingInBoise  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 25
  • Joined: 16-June 12

Re: Odd behavior in change calculator

Posted 12 July 2012 - 02:43 PM

Thank you! That really answers my question quite well. Understanding that the math for type "decimal" is base 10 while other floating point numbers use base 2 helps clear up my confusion greatly.

In response to tlhIn'toq, please don't ever feel like you need to spare my feelings. I am fairly hard to offend, and believe that subtlety is highly overrated. Thank you for your response.
Was This Post Helpful? 1
  • +
  • -

#12 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5316
  • View blog
  • Posts: 11,360
  • Joined: 02-June 10

Re: Odd behavior in change calculator

Posted 12 July 2012 - 02:52 PM

Thanks - I have a rep for being 'Mr. Klingon hard ass'. <laugh>
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1