Get as close to pi as you can

2

Your job is to write a program to find the closest number to PI.

Let me clarify.

You will first choose a number type. Let us say you choose Integer (in an actual answer, you cannot). Your program would then have to generate an integer that is closed to PI. For Integers, this would be 3. Not 4; 3.

For every allowed number type, there will be one and only one closest number, as you will see.

  1. Select your number type. It should only be able to represent rational numbers. You can not make up your own number types. Float or Double is recommended.
  2. Your program will generate a number ctp for "close to PI" (I am just calling it that; you don't have to). 223/71 < ctp < 22/7 must be true (this is why you can't choose Integers). Also, ctp must be the closet number to PI in its number type (although see bonus).
  3. No importing libraries for mathematical functions, operations, etc... (although types are allowed as long, as it obeys #1).
  4. You must somehow output ctp.
  5. You also may not hard code any number (in any type) that uses at least half the precision of your chosen number type.

Bonus: If you use a data type with a precision that depends on machine resources, and it still generates the most accurate approximation possible for any given machine, you can take the pith root of your score. Note: If you code may actually exhaust machine resources, put a warning in. That way people know to use virtual machines to check it (or just check it with their minds).

This is code golf, so shortest program in bytes wins!

Note: The point of this challenge is not just to be another pi calculation challenge. You have to work at the limits of your number type, where all calculations can have detrimental rounding errors. You are doing maximum-precision computing. This is not the same as just outputting a large number of digits.

PyRulez

Posted 2014-02-28T21:02:10.750

Reputation: 6 547

Question was closed 2014-03-01T03:54:39.830

2

Ahem! Floating-point types can represent irrational numbers. Also, this question is almost certainly a duplicate: http://codegolf.stackexchange.com/questions/506/calculate-500-digits-of-pi/ http://codegolf.stackexchange.com/questions/22009/pi-calculation-code-golf

– Jonathan Van Matre – 2014-02-28T21:23:38.350

We have had lots of pi calculation programs. – None – 2014-02-28T21:30:36.737

No this is not a duplicate. My question is meant to test the limits of the number type. We don't have the tag pi for one question. – PyRulez – 2014-02-28T21:40:49.993

3

Also "By their nature, all numbers expressed in floating-point format are rational numbers with a terminating expansion in the relevant base (for example, a terminating decimal expansion in base-10, or a terminating binary expansion in base-2)." -https://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding

– PyRulez – 2014-02-28T21:41:05.730

Pardon me, I should have been more precise, and admittedly it was a nitpick: Floating-point types can "represent" irrational numbers, they just do so inexactly (as rational numbers). My reason for nitpicking is that people will latch on to any loophole and thread their way through it. You might do better to simply state a list of acceptable data types and force people to choose from that. – Jonathan Van Matre – 2014-02-28T22:18:23.573

"For every allowed number type, there will be one and only one closest number, as you will see." I believe this statement is not true for arbitrary precision numbers. – DavidC – 2014-02-28T23:00:39.620

@DavidCarraher It is clarified in the bonus that you just have to get the closet your machine can go. I do know that for some data types its possible to have no closet approximation, but on a given (finite) machine, you will reach a memory limit. – PyRulez – 2014-03-01T01:47:32.640

Please add a rule specifically banning the use of numerical constants derived from pi. 3.1415926535897932384626433832795028842, e.g., is the closest possible approximation for a standard IEEE 64-bit floating-point type, it would be silly to print it or use multiples/factors of it.

– Jason C – 2014-03-01T02:02:00.950

I think it would be covered under no hard coding it in, wouldn't it? – PyRulez – 2014-03-01T02:47:34.590

Oh well. I just said no hard coding overly precise constants. – PyRulez – 2014-03-01T02:52:40.923

1@JasonC the only thing I would add is that's a lot less than the "mere 500 digits" mentioned by the OP in reference to the older question "calculate PI to 500 digits." As a general point, what is the objective winning criterion? greatest digits of accuracy, or shortest code? I guess "float or double is recommended" so I would pick float as that way I have to calculate less digits. – Level River St – 2014-03-01T03:16:08.777

It is just shortest code, but you get a bonus if it is a arbitrary precision data type. Since you can't hard code it anyway, doing float or double doesn't really matter. The logic will be the same. – PyRulez – 2014-03-01T03:21:04.580

1So the question isn't "Get as close to PI as you can at all then". It's "(a) Implement an algorthim that would converge to pi on an ideal machine in the shortest code possible, but (b) at least accurate enough to give the best possible representation in a type of your choosing." (a) has been done before, and (b) is ambiguous. You need to specify the type required to give a level playing field. I suggest a 32 bit float because that way it would be possible to use a double for the inevitably higher precision intermediate values required in calculation. See the first answer to this question. – Level River St – 2014-03-01T03:46:03.427

@PyRulez Can you add the following rules to keep this from degenerating into every other question tagged pi: Nothing from here or here (especially Leibniz series) and no Montecarlo simulations. Otherwise you might as well just go through the answers already on the other pi questions and choose one of those as your winner.

– Jason C – 2014-03-01T03:47:56.137

There's still nothing stopping me from adding up two doubles, each of which encodes half the necessary precision. – user2357112 supports Monica – 2014-03-22T05:55:40.637

Answers

1

C++ 158 chars

#include<iostream>
#include<iomanip>
int main(){double p=0;for(long long l=1;l>0;l+=2){p+=(double)4/l;l+=2;p-=(double)4/l;}std::cout<<std::setprecision(30)<<p;}

Simply calculates pi by brute force until my computer can't store the number to divide 4 by.

I got to 3.1415926535792384 before I killed it. The highlighted part is what is off; it should have been 3.1415926535897932. Eventually, it would have got there.

user10766

Posted 2014-02-28T21:02:10.750

Reputation:

Wait, how exactly does this work? What math is it based on? – PyRulez – 2014-03-01T03:03:46.263

1

@PyRulez It's an expansion of the classic Leibniz series.

– Jason C – 2014-03-01T03:45:46.860

2"Eventually, it would have got there." - would it? I'm pretty sure it wouldn't; there's far too much rounding error that never gets compensated for. – user2357112 supports Monica – 2014-03-22T05:53:00.900

1

Java: 352 chars

import java.math.BigDecimal;class B{public static void main(String[]h){BigDecimal y=v(-3);for(int n=1;n<99;n++)y=y.add(v(n).multiply(v(2).pow(n)).multiply(f(n).pow(2)).divide(f(2*n),42,0));System.out.println(y.toPlainString());}static BigDecimal v(int k){return BigDecimal.valueOf(k);}static BigDecimal f(int k){return k<2?v(1):f(k-1).multiply(v(k));}}

This is a simplification of my answer to another question. It uses the formula from Simon Plouffe, 1996. It only uses addition, multiplication, division and exponentiation on the JDK's built-in class java.lang.BigDecimal.

Idented version:

import java.math.BigDecimal;

class B {
    public static void main(String[] h) {
        BigDecimal y = v(-3);
        for (int n = 1; n < 99; n++)
            y = y.add(v(n).multiply(v(2).pow(n)).multiply(f(n).pow(2)).divide(f(2 * n), 42, 0));
        System.out.println(y.toPlainString());
    }

    static BigDecimal v(int k) {
        return BigDecimal.valueOf(k);
    }

    static BigDecimal f(int k) {
        return k < 2 ? v(1) : f(k - 1).multiply(v(k));
    }
}

This is the output:

3.141592653589793238462643377679212002490611

If you change that 99 and that 42, you might adjust the output. The 99 is the number of iterations (more iterations = more precision). The 42 is the number of decimal digits used in the division (so it rounds beyond that in the case of unexact decimal fractions). For example, using 999 and 420 instead, this is the output:

3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249120347355734950229986020976256234993050320608823801378401335409091901873689012669359599460964434973644188892882434846280102165

Since it is possible to adjust the precision, but only by changing 2 numbers in the source code, but OTOH those numbers have the exact purpose to define the precision, then I don't know if the bonus do applies or do not.

Victor Stafusa

Posted 2014-02-28T21:02:10.750

Reputation: 8 612