Post subject: Pi Program
Player (201)
Joined: 7/6/2004
Posts: 511
If the digits of pi were as interesting as a video game, and the characters of the program were frames, then this is exactly like a time attack. But that's a bit of a stretch so this better go in the Off Topic. I have been working on a new pi program, and I think I have come up with a program that I am satisfied with. Now I want to make sure that it runs properly on all machines, because I do some things that aren't exactly good programming practices to save space. My signature right now, suffers from this problem, it won't actually work on many machines/compilers.
g,o,p,i=1e4,a[10001];main(x){for(;p?g=g/x*p+a[p]*i+2*!o:
53^(printf("%.4d",o+g/i),p=i,o=g%i);a[p--]=g%x)x=p*2-1;}
It should calculate pi to 2880 decimal places. I would like to know if there are any issues you have getting it to compile. There are some problems I already know about but am not willing to add the characters to fix: -not giving type for g,o,p,i,a,main,x. To fix just add int everywhere -printf not declared, include stdio.h If these errors occur, I would still like to know to get an idea of what percent of people have these problems. I have made slightly shorter versions but I am pretty sure that even if they compile, they won't give the same output on all machines. All help is greatly appreciated. In case you are curious the algorithm used is: 2 + 1/3*(2 + 2/5*(2 + 3/7*(2 + 4/9*(...)))) If anyone is interested, here are some other tiny codes I have written: pi to 140 digits in 102 chars
b=1e6,a[27],t,n=995,i;main(){for(;i>24?i=t=!n--,
n--:n^3||cout<<t/n;t=n/2*a[i]+t%n*b,a[i++]=t/n)*a+=8;}
e to 992 digits in 87 chars
N,a[999],x;main(n){for(;n;--n?a[n]=x%n:printf(
"%d",x,n=998+--N))x=x/n+10*(a[n-1]+!~N);}
The algorithm is just like pi, but simpler: 2 + 1/2*(1 + 1/3*(1 + 1/4*(1 + 1/5*(...)))) (same as 1/0!+1/1!+1/2!+1/3!+...)
g,o,p,i=1e4,a[10001];main(x){for(;p?g=g/x*p+a[p]*i+2*!o: 53^(printf("%.4d",o+g/i),p=i,o=g%i);a[p--]=g%x)x=p*2-1;}
Skilled player (1889)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
flagitious wrote:
In case you are curious the algorithm used is: 2 + 1/3*(2 + 2/5*(2 + 3/7*(2 + 4/9*(...))))
I'm not much of a programmer, though I know some math... And I'm curious as to where you came up with this sum? Is it some kind of "Maclaurin-sum"? (I don't know the exact word, but I think you know what I mean)
Player (201)
Joined: 7/6/2004
Posts: 511
Oh I didn't come up with it. It is a common formula for computing pi compactly. I have no idea why or how it works, but it is on my todo list to try to prove this formula. I will post more information about it when I start doing that.
g,o,p,i=1e4,a[10001];main(x){for(;p?g=g/x*p+a[p]*i+2*!o: 53^(printf("%.4d",o+g/i),p=i,o=g%i);a[p--]=g%x)x=p*2-1;}
Player (87)
Joined: 1/15/2006
Posts: 333
Location: Bangkok, Thailand
Compiles fine without modification in vs6.0 under win2k. Is there any reason why it prints out 11 zeros before the digits of pi? This is an awesome program for its size, nice work :)
print reduce(lambda x,p:p/2*x/p+2*10**1000,range(6643,1,-2))
Player (20)
Joined: 10/14/2005
Posts: 317
Hi flag. I did a few tests. ANSI C does allow you to use functions without declaration e.g. printf, but it doesn't specifically permit declaring global variables without a storage class. Consequently, although your first and third programs do compile under gcc, Intel C compiler 9.0, and Visual Studio .NET, they don't work with the IBM XL compiler. As for your second program, I don't see how you could use cout without first including <iostream>, and C++ generally isn't nearly as lax regarding those other things. Thus, I haven't gotten this program to build with any compiler. Edit: And as for output, I tried the top pi program across various compilers on four different operating systems and got the same output each time.
Player (201)
Joined: 7/6/2004
Posts: 511
primordial soup: it prints out 11 leading 0s because fixing that would require me to make it longer, I view these 0s as not that bad, but ideally they wouldn't be there. hanzou, the second program I don't think will compile on any machine without including iostream, but I couldn't resist using it because cout<< is so much shorter than printf("%d",). The reason I don't use it in the first program is because I couldn't find a short way of doing the effect of %.4d which is to pad with 0s as to always print 4 digits. That is some very extensive testing you did, I hadn't even heard of half of those compilers. I am pretty happy with the results. What was the error on IBM XL btw? Thank you both very much for testing those out, I think it is safe for me to change my signature now :) One thing I tried recently was compiling with the -pedantric flag, and it gave me a new warning about g=g/x*p+a[p]*i+2*!o, saying it should be in parenthesis, but whatever. Someone with gcc4 told me that he couldn't get it to compile, he had to include stdio.h, and int declarations, and then would still get an error: /tmp/ccgCaxWP.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0' I have no idea what this means, but my guess was that something was weird about his gcc installation, so I had him just do a hello world test program, and he said that worked. I don't know what to make of that, does anyone have gcc4? Lastly, about the algorithm itself, I have not found much out about it yet, but here is what I have read: it can be derived from the Leibniz series (pi/4=1 - 1/3 + 1/5 - 1/7 + ...), by using Euler's Convergence Transformation. I will try to post more when I find out more. Thanks again for testing!
g,o,p,i=1e4,a[10001];main(x){for(;p?g=g/x*p+a[p]*i+2*!o: 53^(printf("%.4d",o+g/i),p=i,o=g%i);a[p--]=g%x)x=p*2-1;}
Editor, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
flagitious wrote:
he had to include stdio.h, and int declarations
C++ does not allow implicit prototyping. There is no "type defaults to int", so both the variable declarations and your declaration of main() are wrong. Also, iostream (not .h btw) must be included, because in C++ there are unlimited number of ways how a "cout << x" call might be translated, depending which operators are defined for "cout" and with which arguments and attributes. Btw, regarding the compilation problem, tell him to use g++, not gcc, for linking C++ programs. Otherwise it doesn't include libstdc++ in the link. I attempted trying to rewrite your broken C++ example as valid code, but you seem to use the return value of cout::operator<< for something. I don't know what you use it for. cout::operator<< returns a reference to itself, which isn't castable into an int. cout has a cast operator operator bool() which gives a false(0) or true(1) value depending on the success state of the stream, but I'm not sure whether it works in an implicit conversion into int/unsigned type..
Player (201)
Joined: 7/6/2004
Posts: 511
Hmm, these problems with c++ make it not very feasible to be super short :) The return value of cout isn't really used, you could fix it by changing it to (cout<<t/n,1). I didn't get that error, but previously I was using the ? : operator instead || and I would get that error about casting. It is interesting how many different results compilers can give, it is good evidence of two things, that a programmer should always try to write clean code and avoid risky shortcuts, and that c/c++ programmers should probably always compile with some sort of strict standards options, is -ansi sufficient? Here are some of the problems I have had in the past when trying to write real short code: Anything where a value is being modded in the same statement it is being accessed (ie x=n+n--;) Many times I was tempted to do something like this, but it would never be consistant from comp to comp. Arguement order execution (reason old sig didn't work) Array out of bounds effects (I know, very bad programming practice). This is kinda a funny story, current best pi one, before I had the array of size 9999 instead of 10001 to save a character. I knew it was not big enough, but it seemed to work fine. Then when I was changing the names of the variables so I could spell go pi. I started getting different results, I guess gcc decides where put variables in memory based somewhat on alphabetical order, but anyways it is a good thing that happened. I'm sure this stuff is all noted to be standard ambiguous stuff, but still catches me sometimes with, oh it worked, look no further. EDIT: e program improved by 3 characters, I think this will work on all comps so no need to test for me:
a[999],x,n;main(N){for(;n||(putchar(48^x),
n=998+--N);x+=10*a[--n]+!N)a[n]=x%n,x/=n;}
g,o,p,i=1e4,a[10001];main(x){for(;p?g=g/x*p+a[p]*i+2*!o: 53^(printf("%.4d",o+g/i),p=i,o=g%i);a[p--]=g%x)x=p*2-1;}