Is my code suffering from an arithmetic error?

In summary, the code finds the closest fraction to pi within a given range of values by iteratively testing different numerators and denominators. It uses decimal data type for better precision and has a function to reduce the fraction to its simplest form. However, the function mistakenly returns a double value instead of a decimal value.
  • #1
SlurrerOfSpeech
141
11
What it does is described well in my comments. I'm using decimal, which is more precise than double but has a smaller range of values. https://msdn.microsoft.com/en-us/library/ms228360(v=vs.90).aspx

C:
        const decimal pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034m;

        /// <summary>
        /// Finds n,d that minimize |pi - n/d|, where n is in the range 1, 2, ...
        /// and d is in the range [min, max]
        /// </summary>
        /// <remarks>
        /// Can assume min > 0 and min <= max
        /// </remarks>
        static double FindPiFraction(long min, long max, out long n, out long d)
        {
            // Smallest distance between a fraction and pi. Can initialize to Decimal.MaxValue for now.
            decimal smallest = decimal.MaxValue;

            // Placeholders for n, d to satisfy compiler. They are guaranteed to get set to other values below.
            n = -1;
            d = -1;

            // for each possible denominator
            for (long i = min; i <= max; ++i)
            {
                // Begin iterating through numberators. Begin at i * pi rounded down, e.g. if i = 1000
                // then we want to start at 3140. Iterate until our fraction is greater than pi. Keep track
                // of minimum distance between a fraction and pi, and keep track of the numerator and
                // denominator of that fraction.
                for(long j = (long)Math.Floor(Math.PI * (double)i); ; ++j)
                {

                    decimal fraction = (decimal)j / (decimal)i;
                    decimal diff = fraction - pi;
                    decimal distance = diff < 0 ? diff * -1 : diff;
                    if(distance < smallest)
                    {
                        smallest = distance;
                        n = j;
                        d = i;
                    }
                    if(fraction > pi)
                    {
                        break;
                    }
                }
            }
            ReduceFraction(ref n, ref d);
            return n / d;
        }
 
Last edited by a moderator:
Technology news on Phys.org
  • #2
SlurrerOfSpeech said:
What it does is described well in my comments. I'm using decimal, which is more precise than double but has a smaller range of values. https://msdn.microsoft.com/en-us/library/ms228360(v=vs.90).aspx

C:
        const decimal pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034m;

        /// <summary>
        /// Finds n,d that minimize |pi - n/d|, where n is in the range 1, 2, ...
        /// and d is in the range [min, max]
        /// </summary>
        /// <remarks>
        /// Can assume min > 0 and min <= max
        /// </remarks>
        static double FindPiFraction(long min, long max, out long n, out long d)
        {
            // Smallest distance between a fraction and pi. Can initialize to Decimal.MaxValue for now.
            decimal smallest = decimal.MaxValue;

            // Placeholders for n, d to satisfy compiler. They are guaranteed to get set to other values below.
            n = -1;
            d = -1;

            // for each possible denominator
            for (long i = min; i <= max; ++i)
            {
                // Begin iterating through numberators. Begin at i * pi rounded down, e.g. if i = 1000
                // then we want to start at 3140. Iterate until our fraction is greater than pi. Keep track
                // of minimum distance between a fraction and pi, and keep track of the numerator and
                // denominator of that fraction.
                for(long j = (long)Math.Floor(Math.PI * (double)i); ; ++j)
                {

                    decimal fraction = (decimal)j / (decimal)i;
                    decimal diff = fraction - pi;
                    decimal distance = diff < 0 ? diff * -1 : diff;
                    if(distance < smallest)
                    {
                        smallest = distance;
                        n = j;
                        d = i;
                    }
                    if(fraction > pi)
                    {
                        break;
                    }
                }
            }
            ReduceFraction(ref n, ref d);
            return n / d;
        }
Both n and d are declared as long, so n/d is computed using integer division, but you're returning a value of type double.

For example, if n is 19 and d is 10, the value returned will be the double value 1.0. This is very much a rookie error.
 
Last edited:
  • Like
Likes BvU

Related to Is my code suffering from an arithmetic error?

1. How do I know if my code has an arithmetic error?

One way to determine if your code has an arithmetic error is to thoroughly test it with different input values and compare the results to the expected output. If there are discrepancies, it is likely that there is an arithmetic error present.

2. What are some common causes of arithmetic errors in code?

Common causes of arithmetic errors in code include using incorrect data types, not accounting for special cases such as division by zero, and not following the correct order of operations.

3. How can I prevent arithmetic errors in my code?

To prevent arithmetic errors, it is important to thoroughly understand the underlying mathematical principles and ensure that your code is following them correctly. Additionally, using proper error handling techniques and thorough testing can help catch and prevent arithmetic errors.

4. Can arithmetic errors cause other issues in my code?

Yes, arithmetic errors can cause a range of issues in your code, including incorrect calculations, unexpected output, and even program crashes. It is important to identify and fix any arithmetic errors to ensure the overall functionality and accuracy of your code.

5. Are there any tools or techniques to help identify and fix arithmetic errors?

There are various tools and techniques that can help identify and fix arithmetic errors, such as debugging tools, unit testing, and code review by peers. It is also helpful to have a strong understanding of mathematical principles and to carefully review and test your code for any potential errors.

Similar threads

  • Programming and Computer Science
Replies
2
Views
1K
  • Programming and Computer Science
Replies
2
Views
2K
  • Programming and Computer Science
2
Replies
54
Views
4K
  • Math Proof Training and Practice
3
Replies
100
Views
7K
  • MATLAB, Maple, Mathematica, LaTeX
Replies
2
Views
1K
  • Programming and Computer Science
2
Replies
49
Views
10K
  • Math Proof Training and Practice
2
Replies
52
Views
9K
  • General Math
4
Replies
125
Views
17K
  • Math Proof Training and Practice
2
Replies
48
Views
8K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
6K
Back
Top