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);
}
}
%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.
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.
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.
// 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
Related
Im new to C and I really don't know know what I'm doing wrong.
The issue that I am having is I'm supposed to ask 3 questions of the user using scanf. I'm supposed to ask the user for an integer, a positive real number and a non negative number and then calculate the numbers into XX.XX using %.2f.
//pre-processor directives
#include <stdio.h>
#include <math.h>
//main function
int main()
{
//declare variables
int smp1,smp2, smp3,total;
printf("sample 1?\n"); // positive integer
scanf("%d", &smp1);
printf("sample 2?\n"); //positive real number
scanf("%f",&smp2);
printf("sample 3?\n"); // non negative number
scanf("%u", &smp3);
total = (smp1 + smp2 / smp3);
printf("The final result is %.2f",total);
//end of main
return 0;
}
No matter what I put in there my result ends up being 0.00. It won't even do simple addition and I don't know enough to know why.
Your main issue is that you declare all your variables as ints, but smp2 and total must hold floating point values.
Change your declarations to
int smp1;
double smp2, total;
unsigned int smp3;
This way, the types of the variables match up with the conversion specifiers used in the printf and scanf calls.
Types matter in C, and it's up to you that the types of the arguments in each printf and scanf call match up with the conversion specifiers.
Check your compiler documentation on how to enable warnings (even better, to treat all warnings as errors). Most compilers should warn about type mismatches like this, but sometimes you have to set a flag in order for those warnings to appear.
there's something wrong in these variables.
can someone fix this? my answer keep getting on 0.00
Test case:
we want to find the mean between 3 numbers using struct
input=2,
2 of them are: 3 5 8 and 3 5 7
out put should be:
//*3+5+8=(16)/3=5.33
//*3+5+7=(15)/3=5.00
#include<stdio.h>
struct rata{
float in1;
float in2;
float in3;
};
float rata2(in1,in2,in3){
return (float)((in1+in2+in3)/3);
}
void main(){
int i,n;
char hasil[100];
scanf("%d",&n);
struct rata walao;
for (i=0;i<n;i++){
scanf("%d %d %d",&walao.in1,&walao.in2,&walao.in3);
hasil[i]=rata2(walao.in1,walao.in2,walao.in3);
}
for (i=0;i<n;i++){
printf("%.2f\n",hasil[i]);
}
}
There are 3 errors in your code that is preventing you from getting the correct answer. Can you find them? Here's a hint, they have to do with types.
Below are the answers and the reasons behind them.
char hasil[100] is assigning hasil to be a char array of size 100. While chars can be assigned numerical values, they are to be treated as integers if they are. Floats =/= Integers, and this should be rectified by saying float hasil[100]
scanf("%d %d %d",&walao.in1,&walao.in2,&walao.in3) is scanning for 3 digits. Since floats can also be assigned integer values, this is valid. However, the language requires that all values used in a calculation should be the same type (hint for 3!). To fix you can do 1 of 2 things, both are legal but entirely up to you. You can either write it as scanf("%f %f %f",&walao.in1,&walao.in2,&walao.in3) or keep it as is. Your choice will come to play in final error
The input rata2 is taking is unspecified. Is it ints? floats? chars? It doesn't know but it trys to resort to using ints, as mostly everything in C can be represented by a number. Since it resorts to ints, the value returned by your calculation is an int as well and no late cast to float will change that. Those variables need to be specified as something and how you handled error 2 decides what you do here. If you changed the earlier scanf to take floats instead of digits, rewrite rata as float rata2(float in1, float in2, float in3), remove the cast and you're done. If you kept as is, rewrite rata as float rata2(int in1, int in2, int in3), and rewrite the return as return ((float)in1 + (float)in2 + (float)in3)/3;. Either course of action is acceptable but its far more easier and faster specifying them as floats then trying to cast everything (Plus its a LOT cleaner).
This should rectify your code (tested it on my machine). Also, for future note, do
scanf("%d",&n);float hasil[n];
It makes more sense and you don't have to run into the issue of people specifying memory you don't have access to.
#include <stdio.h>
int main(){
int n, v;
printf("Please enter a value from 39 to 59: \n");
scanf("%d", &n);
printf("Please enter a value from 3 to 7: \n");
scanf("%d", &v);
}
When I got those values from user, how can I perform this factorial calculation:
n! / ((n-v)! * v!))
I've tried different data types but apparently none can hold the result.
For example: n = 49, v=6. The result is: 13,983,816, but how can I go about getting it?
You're best bet is to ditch the naive factorial implementations, usually based on recursion, and switch to one that returns the natural log of gamma function.
The gamma function is related to factorial: gamma(n) = (n-1)!
Best of all is natural log of gamma, because you can rewrite that expression like this:
ln(n!/(n-v)!v!) = ln(n!) - ln((n-v)!) - ln(v!)
But
(n-v)! = gamma(n-v+1)
n! = gamma(n+1)
v! = gamma(v+1)
So
ln(n!/(n-v)!v!) = lngamma(n+1) - lngamma(n-v+1) - lngamma(v+1)
You can find an implemenation for lngamma in Numerical Recipes.
lngamma returns a double, so it'll fit even for larger values.
It should go without saying that you'll take exp() of both sides to get the original expression you want back.
#duffymo idea looked like too much fun to ignore: use lgamma() from <math.h>.
Results past maybe x=1e15, start to lose the trailing significant digits.. Still fun to be able to get 1000000.0!.
void factorial_expo(double x, double *significand, double *expo) {
double y = lgamma(x+1);
const static double ln10 = 2.3025850929940456840179914546844;
y /= ln10;
double ipart;
double fpart = modf(y, &ipart);
if (significand) *significand = pow(10.0, fpart);
if (expo) *expo = ipart;
}
void facttest(double x) {
printf("%.1f! = ", x);
double significand, expo;
factorial_expo(x, &significand, &expo);
int digits = expo > 15 ? 15 : expo;
if (digits < 1) digits++;
printf("%.*fe%.0f\n", digits, significand, expo);
}
int main(void) {
facttest(0.0);
facttest(1.0);
facttest(2.0);
facttest(6.0);
facttest(10.0);
facttest(69.0);
facttest(1000000.0);
return 0;
}
0.0! = 1.0e0
1.0! = 1.0e0
2.0! = 2.0e0
6.0! = 7.20e2
10.0! = 3.628800e6
69.0! = 1.711224524281441e98
1000000.0! = 8.263931668544735e5565708
In a comment, you've finally said that you don't need exact results.
Just use floating-point. The largest intermediate result you'll need to handle is 59!, which is about 1.3868e80; type double is more than big enough to hold that value.
Write a function like:
double factorial(int n);
(I presume you know how to implement it) and use that.
If you're going to be doing a lot of these calculations, you might want to cache the results by storing them in an array. If you define an array like:
double fact[60];
then you can store the value of N! in fact[N] for N from 0 to 59 -- and you can fill the entire array in about the time it would take to compute 59! just once. Otherwise, you'll be doing several dozen floating-point multiplications and divisions on each calculation -- which is trivial if you do it once, but could be significant if you do it, say, thousands or millions of times.
If you needed exact results, you could use an extended integer library like GNU MP, as others have suggested. Or you could use a language (like Python, for example) that has built-in support for arbitrary-length integers.
Or you could probably perform the multiplications and divisions in an order that avoids overflow; I don't know exactly how to do that, but since n! / ((n-v)! * v!)) is a common formula I strongly suspect that work has already been done.
You can't work with such long numbers as 59! in simple way.
However you can use special C libraries which are working with long numbers bigger than 8 bytes, for example GMP
#include<stdlib.h>
#include<stdio.h>
long double fact(unsigned long int n)
/*The factorial of a positive integer by recursion*/
{
if (n==0)
return 1;
else
return n*fact(n-1);
}
int main()
{
long double sum, n;
int i, m;
printf("\t/*Code to find the approximate value of e */");
check:
printf("\n\n\tPlease Enter the value of n := ");
scanf("%lf", &n);
sum=0;
for (i=0; i<=n; i++)
sum +=1/(fact(i));
printf("\n\n\tThe appriximate value of e := %.15lg\n\n\t", sum);
printf("Let's do this again? 1/ YES Any key/ NO := ");
scanf("%d", &m);
if (m==1)
goto check;
else (1);
return 0;
}
This code worked perfectly well with Visual C++ 2010 but not with DEV C++. It kept on returning zero for the value of e. Can someone please explain why! Thanks!
use this scanf("%Lf", &n); the Format specifier of long double is %Lf,%le,%lg so use this
and also consider these point
Dev-C++ It uses GCC (MinGW). No ammount of Dev-C++ updates will fix this issue.
Dev-C++ has not been updated for 5 years; don't hold your breath.
The derivative wxDev-C++ is maintained.
If you want a compiler update, go to www.mingw.org, and hope that the latest version still works with the ancient Dev-C++. Or use a different IDE or compiler. I'd recommend VC++ 2010 Express Edition (Free, and a far better debugger), your code works as is in VC++ 2008, but that does not make it safe.
How did you determine the value was "0"? It is likely that it was in fact something like 0.000001, and your method of interrogation rounded it. You should view the value in the debugger rather than a print statement. Unfortunately Dev-C++'s debugger sucks.
The ISO C standard library defines functions only for double precision. If you want versions defined for float, you need to compile as C++ and include . C does not support function overloading, so it is impossible to do in C without differently named functions.
scanf("%lf", &n);
%lf conversion specification is used to read a double.
You have to use %Lf to read a long double.
did you check wheter scanf(...) really reads the number you want to read? Try to print the value you read. And also the line
sum +=1/(fact(i));
looks suspicious. 1 as an integer divided by something bigger than 1 should always yield 0, in the optimal case on every compiler... Maybe you could try this instead:
sum +=1.0/(fact(i));
EDIT: Sorry was wrong here. Typeconversions make it possible to devide integer by long double.
Ok, i'm writing in c here. Compiling in mingw gcc.
I'm trying to do something really simple. create a vector struct containing 3 floats x,y,z.
then I want to be able to do some math with them.
This is my short test program:
#ifndef _PHYSICS_C_
#define _PHYSICS_C_
#define SUCCESS 0
#define FAILURE 1
typedef struct {
float x;
float y;
float z;
}vector;
int add ( vector* a, vector* b, vector* destination ){
(*destination).x = (float)( ((*a).x) + ((*b).x) );
(*destination).y = (float)( ((*a).y) + ((*b).y) );
(*destination).z = (float)( ((*a).z) + ((*b).z) );
return SUCCESS;
}
int main(int argc, char** argv){
printf("creating vectors\n\n");
vector a = {1.0f,5.0f,3.0f};
vector b = {2.0f,3.0f,6.0f};
vector destination;
printf("adding vectors\n\n");
if(add(&a, &b, &destination) == SUCCESS){
printf("result: (%d, %d, %d)\n\n",destination.x,destination.y,destination.z);
} else {
printf("the program failed somehow...\n\n");
}
printf("Press any key to continue...\n");
getchar();
return SUCCESS;
}
#endif
When I compile and run it, it should return (3, 8, 9) the sum of vectors a and b.
instead it returns (0, 1074266112, 0)...
I can't figure out what is wrong.
for some reason I think that I must somehow be writing over memory I'm not supposed to.
x,y,z are floats but you are trying to print them as integers.
try:
printf("result: (%f, %f, %f)\n\n",destination.x,destination.y,destination.z);
check man printf or your documentation to see all of the specifiers for printf.
%d expects int. Use %f or %g for floats/doubles.
Identifiers starting with an underscore followed by an uppercase letter are reserved; don't use them in your own code.
Include guards (#ifndef _PHYSICS_C_ ...) are for header files, not for .c files.
printf requires #include <stdio.h>.
You're returning the value SUCCESS from main(). That's ok, since SUCCESS happens to be 0, but it would be clearer to use either EXIT_SUCCESS (declared in <stdlib.h> or just return 0;.
You add function always returns SUCCESS. It might as well be a void function (and the test for its value in main is not useful). Unless you anticipate adding error checking later on.
The casts in your add function are unnecessary; the expression is already of type float. And (*foo).bar is better written as foo->bar. For example, the first assignment can be simplified to destination->x = a->x + y->x;.
The real problem (which has already been pointed out) is that you're using a "%d" format for values of type float.
It's usual to use double rather than float. It has more precision, and modern hardware is often optimized for double-precision operations.
If you enable warnings in your compiler, it will probably tell you about some of these problems.
You are printing float with format specifier %d which is intended for signed int. Use %f or %g or %e instead .
Also, why don't you do:
destination->x = a->x + b->x;
Its much easier on the eyes. (although not a problem).