Calculating and printing factorial at compile time in C++
The factorial can be printed in compiler-generated message as:
template<int x> struct _;
int main() {
_<Factorial<10>::value> __;
return 0;
}
Error message:
prog.cpp:14:32: error: aggregate ‘_<3628800> __’ has incomplete type and cannot be defined
_::value> __;
^
Here 3628800
is factorial of 10
.
See it at ideone : http://ideone.com/094SJz
So are you looking for this?
EDIT:
Matthieu asked for a clever trick to both print the factorial AND let the compilation continue. Here is one attempt. It doesn't give any error, hence the compilation succeeds with one warning.
template<int factorial>
struct _{ operator char() { return factorial + 256; } }; //always overflow
int main() {
char(_<Factorial<5>::value>());
return 0;
}
It gets compiled with this warning:
main.cpp: In instantiation of '_::operator char() [with int
factorial = 120]': main.cpp:16:39: required from here
main.cpp:13:48: warning: overflow in implicit constant conversion
[-Woverflow] struct _{ operator char() { return factorial + 256; } };
//always overflow
Here 120
is factorial of 5
.
Demo at ideone : http://coliru.stacked-crooked.com/a/c4d703a670060545
You could just write a nice macro, and use it instead as:
#define PRINT_AS_WARNING(constant) char(_<constant>())
int main()
{
PRINT_AS_WARNING(Factorial<5>::value);
return 0;
}
That looks great.
Is it possible to calculate number factorial at compile time, but without enums
While there are alternative notations, It's written that way because more compilers accept that enum-style notation. The language supports const integral-type class members with an inline initialization, but some compilers aren't compliant with the standard in that regard. On compilers that are compliant in this regard, the following works just fine:
#include <iostream>
template <unsigned int n>
struct fact
{
static const unsigned int value = n*fact<n-1>::value;
};
template<>
struct fact<0>
{
static const unsigned int value = 1;
};
int main()
{
std::cout << fact<10>::value << "\n";
}
Printing sizeof(T) at compile time
Yes. The possible duplicate prints the size as error message, which means the compilation will not succeed.
However, my solution prints the size as warning message, which means, it will print the size, and the compilation will continue.
template<int N>
struct print_size_as_warning
{
char operator()() { return N + 256; } //deliberately causing overflow
};
int main() {
print_size_as_warning<sizeof(int)>()();
return 0;
}
Warning message:
prog.cpp: In member function ‘char print_size_as_warning<N>::operator()() [with int N = 4]’:
prog.cpp:8: instantiated from here
prog.cpp:4: warning: overflow in implicit constant conversion
Demo : http://www.ideone.com/m9eg3
Note : the value of N in the warning message is the value of sizeof(int)
The above code is improved one, and my first attempt was this:
template<int N>
struct _{ operator char() { return N+ 256; } }; //always overflow
int main() {
char(_<sizeof(int)>());
return 0;
}
Warning message:
prog.cpp: In member function ‘_<N>::operator char() [with int N = 4]’:
prog.cpp:5: instantiated from here
prog.cpp:2: warning: overflow in implicit constant conversion
Demo : http://www.ideone.com/mhXjU
The idea is taken from my previous answer to this question:
- Calculating and printing factorial at compile time in C++
Factorial with while loop in C
Firstly, scanf
expects the address of Wert
, not its value, and also update your while
loop to compare with 1
. Here's the fixed version:
#include <stdio.h>
int main(void)
{
int Wert;
int fak = 1;
scanf ("%d", &Wert);
while ( Wert > 1 ) {
fak = fak * Wert;
Wert = Wert - 1;
}
printf ("%d", fak);
}
Input:
5
Output:
120
But since factorials easily overflow integers, it may be a better idea to use double
instead:
#include <stdio.h>
double fact(double d)
{
if (d < 1.0)
return 1.0;
return d * fact(d - 1.0);
}
int main(void)
{
double d = 0;
if (scanf("%lf", &d) != 1) {
perror("Failed to read stdin");
return -1;
}
printf("%lf! = %lf", d, fact(d));
return 0;
}
Input:
100
Output:
100.000000! = 93326215443944102000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
Just keep in mind that floating point math is broken.
C program to find the sum of factorials
There are some mistakes in your code.
The first one, is very common when we start learning C
1 / fact
must be replaced by 1.0f / fact
Why? Because in C, 1 / 2
is performed using integer arithmetic and returns 0
. If you want to perform computation using floating numbers you must force at least one argument being a floating number, this can be done by 1.0/2
, 1/2.0
or 1.0/2.0
. The previous expressions will be evaluated using double
floating number type (which is the C default type for floating number). If you want to use simple precision floating numbers, float
, you can use 1.0f
the second one is certainly an inadvertent error:
sum += fact;
must be replace by sum += term;
Here is a "working" code
#include <stdio.h>
void
main()
{
/*Any problems with the variables ?*/
int i, lim, fact = 1;
float sum = 0.0, term;
printf("Enter the limit for the sum of series: ");
scanf("%d", &lim);
/*Any problems in the loop ? */
for (i = 1; i <= lim; i++)
{
fact *= i;
term = 1. / fact; /* instead of 1/fact */
sum += term; /* instead of sum += fact */
}
printf("%f is the sum of the series\n", sum);
}
Enter the limit for the sum of series: 5
1.716667 is the sum of the series
There is a more subtle error. By instance, if you want lim = 50
,
Enter the limit for the sum of series: 50
inf is the sum of the series
The reason is that 50!
is way too big to be stored in an int
.
The solution is to compute directly 1/i!
using floating number (and not i!
using int
then 1/i!
)
A modified program, that also uses double
for an higher precision is :
#include <stdio.h>
void
main()
{
/*Any problems with the variables ?*/
int lim;
double sum = 0.0, term = 1.0;
printf("Enter the limit for the sum of series: ");
scanf("%d", &lim);
/*Any problems in the loop ? */
for (int i = 1; i <= lim; i++)
{
term = term / i;
sum += term;
}
printf("%f is the sum of the series\n", sum);
}
that now works, even when lim=50
Do not be discouraged by these mistakes. These are mistakes we all made when we learned C !
Expected result:
exp(1) = exp(0) + sum_{i=1}^\infty 1/i!
thus your expected result is exp(1)-exp(0) = 1.718281828459045....
Calculate the factorial of an arbitrarily large number, showing all the digits
GNU Multiprecision library is a good one! But since you say using of external libraries are not allowed, only way I believe its possible is by taking an array of int and then multiplying numbers as you do with pen on paper!
Here is the code I wrote some time back..
#include<iostream>
#include<cstring>
int max = 5000;
void display(int arr[]){
int ctr = 0;
for (int i=0; i<max; i++){
if (!ctr && arr[i]) ctr = 1;
if(ctr)
std::cout<<arr[i];
}
}
void factorial(int arr[], int n){
if (!n) return;
int carry = 0;
for (int i=max-1; i>=0; --i){
arr[i] = (arr[i] * n) + carry;
carry = arr[i]/10;
arr[i] %= 10;
}
factorial(arr,n-1);
}
int main(){
int *arr = new int[max];
std::memset(arr,0,max*sizeof(int));
arr[max-1] = 1;
int num;
std::cout<<"Enter the number: ";
std::cin>>num;
std::cout<<"factorial of "<<num<<"is :\n";
factorial(arr,num);
display(arr);
delete[] arr;
return 0;
}
'arr' is just an integer array, and factorial is a simple function that multiplies the given number to the 'large number'.
Hope this solves your query..
C program for calculating the value of e
For more precision I would use double
instead of float
.
for (i=1; i<=n, i++)
e= 1+1/factorial(i);
This is wrong, you are not adding to e, you are assigning always the last
value of the series, which is always 0 (except for i = 1). So your e will
always be 1.
factorial
is a function that returns an int
. A int
divided by an int
is
an int
and in C anything 1/x (for x > 1, x integer) is 0. You you to use1.0
or cast at least one of the arguments to double
(or float
if you are
using floats):
double e = 1; // initializing e
for(i = 1; i <= n; ++i)
e += 1.0/factorial(i);
Also, the value of 1/n! must be calculated until it's value is smaller than epsilon, also entered by the user.
I don't understand what that means, if n is a fixed value given by the user,
what do you keep calculating? Is this really what the exercise says?
My interpretation would be: if by n steps |e_real - e_calculated| > epsilon,
keep incrementing n, otherwise stop. That would be
#include <stdio.h>
#include <math.h>
#include <stdint.h>
uint64_t factorial (uint64_t i)
{
if (i==0)
return 1;
else
return i*factorial(i-1);
}
int main(void)
{
int n;
double e = 1;
double epsilon;
printf("what is the value of epsilon: ");
scanf("%lf", &epsilon);
printf("what is the value of n: ");
scanf("%d",&n);
int i = 1;
while(1)
{
e += 1.0/factorial(i++);
if(i >= n && (fabs(e - M_E) < epsilon))
break;
}
printf("e: %.20lf, calculated e: %.20lf, error: %.20lf, steps: %d\n", M_E, e, fabs(e-M_E), i);
return 0;
}
Note: if you are using GCC, you have to compile it with the -lm
option:
$ gcc e.c -oe -lm
3 Function plus Main Function C Program calculating and displaying a Factorial
First of all, you should change your call to GetData
to :
GetData(&x);
as you want to pass a pointer. Then, its declaration should change to :
void GetData(int *x)
{
printf("Please enter a number:\n");
scanf("%d%*c", x);
}
Then, you should return variable factorial
instead of x
. Change line :
return(x);
to :
return(factorial);
and consequently call Factorial
function as follows :
factorial = Factorial(x);
as right now, variable factorial
is uninitialized, and by passing it to Factorial
you will be getting garbage, as you said.
calculating factorial using template meta-programming
- What is this weird template that takes
<int N>
?
In C++, template arguments can either be types (prefixed with class
or typename
) or integers (prefixed with int
or unsigned int
). Here we are in the second case.
- What is this second weird
template <>
?
template<> struct Factorial<0>
is a complete specialization of Factorial class template, which means that 0
is considered a special value to which corresponds its own version of Factorial.
- What are the enums for?
enums are the way to compute values in metaprogramming C++
- What is the advantage of using this rather than normal runtime factorial calculation?
The reason why this code was created in the first place is to create a proof of concept that calculus can be done using metaprogramming. The advantage is that generated code is extremely efficient (calling Factorial<4>::value
is equivalent to simply writing "24" in your code.
- How often do you people use this? I have been using C++ for a while now, but never used this before. How big a part of C++ was I missing out on?
Such functionality is rarely achieved using this method, but metaprogramming is used more and more nowadays. See Boost meta-programming library to get a hint of what can be done.
Related Topics
Is Returning References of Member Variables Bad Practice
What Is the Comdat Section Used For
Printing Double Without Losing Precision
C++11 Anonymous Union with Non-Trivial Members
Efficiently Reading a Very Large Text File in C++
Std::Lexical_Cast - Is There Such a Thing
How to Pass Derived Classes by Reference to a Function Taking Base Class as a Parameter
Pros & Cons of Putting All Code in Header Files in C++
Why Does This Simple Std::Thread Example Not Work
Reading an Application's Manifest File
Replace Multiple Spaces with One Space in a String
How Does C++ Link Template Instances
Cost of Throwing C++0X Exceptions
The Implementation of Random_Device in VS2010
C++ Class Wrapper Around Fundamental Types
Why Does Constexpr Static Member (Of Type Class) Require a Definition