2
\$\begingroup\$

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.

\$\endgroup\$

closed as too broad by TheDoctor, Jason C, Justin, Level River St, Doorknob Mar 1 '14 at 3:54

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    \$\begingroup\$ Ahem! Floating-point types can represent irrational numbers. Also, this question is almost certainly a duplicate: codegolf.stackexchange.com/questions/506/… codegolf.stackexchange.com/questions/22009/… \$\endgroup\$ – Jonathan Van Matre Feb 28 '14 at 21:23
  • \$\begingroup\$ We have had lots of pi calculation programs. \$\endgroup\$ – Hosch250 Feb 28 '14 at 21:30
  • 3
    \$\begingroup\$ 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)." -en.wikipedia.org/wiki/… \$\endgroup\$ – PyRulez Feb 28 '14 at 21:41
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – Level River St Mar 1 '14 at 3:16
  • 1
    \$\begingroup\$ So 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. \$\endgroup\$ – Level River St Mar 1 '14 at 3:46
1
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Wait, how exactly does this work? What math is it based on? \$\endgroup\$ – PyRulez Mar 1 '14 at 3:03
  • 1
    \$\begingroup\$ @PyRulez It's an expansion of the classic Leibniz series. \$\endgroup\$ – Jason C Mar 1 '14 at 3:45
  • 2
    \$\begingroup\$ "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. \$\endgroup\$ – user2357112 Mar 22 '14 at 5:53
1
\$\begingroup\$

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.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.