60

I'm doing a program that aproximate PI and i'm trying to use long long, but it isn't working. Here is the code

#include<stdio.h>
#include<math.h>
typedef long long num;
main(){
    num pi;
    pi=0;
    num e, n;
    scanf("%d", &n);
    for(e=0; 1;e++){
      pi += ((pow((-1.0),e))/(2.0*e+1.0));
      if(e%n==0)
        printf("%15lld -> %1.16lld\n",e, 4*pi);
      //printf("%lld\n",4*pi);
    }
}
guerda
  • 23,388
  • 27
  • 97
  • 146
Carlos
  • 601
  • 1
  • 5
  • 3

4 Answers4

76

%lld is the standard C99 way, but that doesn't work on the compiler that I'm using (mingw32-gcc v4.6.0). The way to do it on this compiler is: %I64d

So try this:

if(e%n==0)printf("%15I64d -> %1.16I64d\n",e, 4*pi);

and

scanf("%I64d", &n);

The only way I know of for doing this in a completely portable way is to use the defines in <inttypes.h>.

In your case, it would look like this:

scanf("%"SCNd64"", &n);
//...    
if(e%n==0)printf("%15"PRId64" -> %1.16"PRId64"\n",e, 4*pi);

It really is very ugly... but at least it is portable.

Florian Winter
  • 4,750
  • 1
  • 44
  • 69
karadoc
  • 2,641
  • 22
  • 21
  • 11
    It's not your compiler but your C library that's responsible here. You're using the Microsoft C library, which doesn't support `%lld`, which is a C99 feature (although so is `inttypes.h`). – caf Jun 20 '11 at 02:59
  • 1
    To be more specific, it's msvcrt.dll, which is the ancient (circa 1998) version of the C standard library that was originally written for VC++ 6.0, and ships with Windows for backwards compatibility purposes. MinGW uses that ancient version, because that's the only one that comes out of the box with Windows. But modern VC++ runtime handle `%lld` properly. – Pavel Minaev Sep 16 '16 at 01:36
  • 1
    Visual C++ 2013 seems to support the %lld format element – user1741137 May 03 '17 at 17:38
  • 1
    @PavelMinaev msvcrt.dll that comes with windows isn't ancient. – Pavel P May 18 '17 at 18:19
  • It has been patched, sure, but I haven't heard of any updates to its actual features since VC++ 6.0 days. – Pavel Minaev May 19 '17 at 00:26
  • One of the benefits of using new WSL is you can be in the modern days of writing C with updated GCC or CLANG. Much more compatible than MINGW. – Brian Bulkowski May 24 '20 at 23:41
3
  • Your scanf() statement needs to use %lld too.
  • Your loop does not have a terminating condition.
  • There are far too many parentheses and far too few spaces in the expression

    pi += pow(-1.0, e) / (2.0*e + 1.0);
    
  • You add one on the first iteration of the loop, and thereafter zero to the value of 'pi'; this does not change the value much.
  • You should use an explicit return type of int for main().
  • On the whole, it is best to specify int main(void) when it ignores its arguments, though that is less of a categorical statement than the rest.
  • I dislike the explicit licence granted in C99 to omit the return from the end of main() and don't use it myself; I write return 0; to be explicit.

I think the whole algorithm is dubious when written using long long; the data type probably should be more like long double (with %Lf for the scanf() format, and maybe %19.16Lf for the printf() formats.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0
    // acos(0.0) will return value of pi/2, inverse of cos(0) is pi/2 
    double pi = 2 * acos(0.0);
    int n; // upto 6 digit
    scanf("%d",&n); //precision with which you want the value of pi
    printf("%.*lf\n",n,pi); // * will get replaced by n which is the required precision
Atul Kumar
  • 690
  • 1
  • 9
  • 20
  • 2
    While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion – Rahul Gupta Dec 29 '17 at 11:22
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – double-beep Mar 31 '19 at 11:22
  • Sure, I will add some more details @double-beep – Atul Kumar Mar 31 '19 at 11:24
0

First of all, %d is for a int

So %1.16lld makes no sense, because %d is an integer

That typedef you do, is also unnecessary, use the type straight ahead, makes a much more readable code.

What you want to use is the type double, for calculating pi and then using %f or %1.16f.

Vinicius Kamakura
  • 7,665
  • 1
  • 29
  • 43
  • It's not really "illegal"... it's MSVC-specific, I think. – user541686 Jun 19 '11 at 02:41
  • 7
    Incorrect. Read the [spec for printf](http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html). `%lld` is exactly how you print a `long long`. (Of course, the `1.16` may not do what you want... But it is perfectly valid. It means use a minimum field width of 1 and to print 16 digits.) – Nemo Jun 19 '11 at 02:44
  • @Mehrdad You mean `%lld`? It's specified in C99 7.19.6.1. – Pascal Cuoq Jun 19 '11 at 02:45
  • @Pascal: Oh I had no idea, even better then. @hexa: Sorry I was referring to `lld`, not decimal points... I thought that's what you meant, my bad. – user541686 Jun 19 '11 at 02:46
  • 1
    [MSVC](http://msdn.microsoft.com/en-us/library/56e442dc%28v=vs.80%29.aspx) uses a format such as `%I64d` or `%lld` for the 64-bit `long long` formats. – Jonathan Leffler Jun 19 '11 at 03:50