Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Why it is giving runtime error while adding printf statement in the last? And just after the removing the printf statement, no error.
#include <stdio.h>
#define MOD 1000000007
#define MAX 44721
int main() {
long long int test, i, j, store[1000009], n, m, x, a[1000006];
scanf("%lld", &test);
for (i = 0; i < 1000006; i++) {
store[i] = 1LL;
}
a[0] = 1;
for (j = 1; j < 1000006; j++) {
for (i = 1; i < MAX; i++) {
if (i % 2 == 0) {
store[i] = (store[i - 1] + store[i]) % MOD;
}
}
a[j] = store[MAX - 1];
}
printf("%lld", a[1]);
return 0;
}
First of all you should pick a language as C is different from C++.
As your code is C my solution will be in C too.
Running your code under Valgrind cleary shows that you are experiencing a stack overflow. The size of the arrays on the stack are too big.
Valgrind output:
==14228== Invalid write of size 4
==14228== at 0x100000DC7: main (prova.c:6)
==14228== Address 0x1038c062c is on thread 1's stack
==14228== in frame #0, created by main (prova.c:6)
The size of the stack is system-dependent, the default on many system is 8MB, on unix/linux you can see it issuing the commnad ulimit -a. You may want to look at this post for more information about how stack and heap works.
The correct solution is to allocate arrays dynamically:
store = malloc(1000009 * sizeof(long long int));
if (store == NULL) {
// The memory allocation failed, exit
return(1);
}
a = malloc(1000006 * sizeof(long long int));
if (a == NULL) {
return(1);
}
Remember to always check the return value of malloc ;)
You allocate 2 large arrays of long long int in automatic storage, that's more than 8MB of stack space. You probably cause a stack overflow. It is possible that the compiler optimizes out most of your code if you remove the printf since none of it has any observable behavior without it.
In C, allocate the arrays with malloc:
#include <stdio.h>
#define MOD 1000000007
#define MAX 44721
int main(void) {
long long int test, i, j, n, m, x;
long long int *store = malloc(1000009 * sizeof(*store));
long long int *a = malloc(1000006 * sizeof(*a));
scanf("%lld", &test);
for (i = 0; i < 1000006; i++) {
store[i] = 1LL;
}
a[0] = 1;
for (j = 1; j < 1000006; j++) {
for (i = 1; i < MAX; i++) {
if (i % 2 == 0) {
store[i] = (store[i - 1] + store[i]) % MOD;
}
}
a[j] = store[MAX - 1];
}
printf("%lld", a[1]);
return 0;
}
There's 2 main problems here.
Your code is probably failing because of retrun 0; (fix: return 0;)
Second, you are allocating 2 really big array in the stacks, and you will, 99% of the times, end up getting stack overflow;
Note: long long int, is the same as long long:
You should consider using:
std::vector<long long> store(10000009);
or
std::unique_ptr<long long[]> store = std::make_unique<long long[]> (10000009);
or
long long* store = new long long[10000009]
or
auto* store = new long long[10000009]
or if you are using c... since you have both tags
long long* store = (long long *)malloc(sizeof(long long) * 10000009);
or if you are using MSVC, you can use the __int64 keyword if what you want is a int of 64 bits [8 bytes])
std::vector<__int64> store(1345134123);
I normally prefer that over long long
And you could do a typedef long long __int64 if you end up using another compiler.
Related
The below given code is not working for high value (eg: 51574523448, 1000000000000, etc) even after using long long and giving some different different values but is properly working for low values.
Can anyone explain what is the problem and how to solve it. (Sorry for weak english).
int repeatedString(string s, long n) {
long count = 0;
int secondCount = 0;
long num;
int length = s.length();
double remainder;
num = (long) n / (length);
remainder = n % (length);
for(int i=0; i < length; i++) {
if(s[i]=='a') {
count++;
if(i < remainder)
secondCount++;
}
}
count = count*num + secondCount;
return count;
}
Try running this program on your platform:
#include <iostream>
#include <limits>
int main()
{
std::cout << std::numeric_limits<long>::max() << '\n';
}
The number it prints is the maximum value a long can store. I get 2147483647, which is much less than 51574523448. You will likely need to use a larger data type, such as long long.
I'm using a server with 128GB memory to do some computation. I need to malloc() a 2D float array of size 56120 * 56120. An example code is as follows:
int main(int argc, char const *argv[])
{
float *ls;
int num = 56120,i,j;
ls = (float *)malloc((num * num)*sizeof(float));
if(ls == NULL){
cout << "malloc failed !!!" << endl;
while(1);
}
cout << "malloc succeeded ~~~" << endl;
return 0;
}
The code compiles successfully but when I run it, it says "malloc failed !!!". As I calculated, it only takes about 11GB of memory to hold the whole array. Before I started the code, I checked the server and there was 110GB of free memory available. Why does the error happen?
I also found that if I reduce num to, say 40000, then the malloc will succeed.
Does this mean that there is a limit on the maximum memory that can be allocated by malloc()?
Moreover, if I change the way of allocation, directly declaring a 2D float array of such size, as follows:
int main(int argc, char const *argv[])
{
int num = 56120,i,j;
float ls[3149454400];
if(ls == NULL){
cout << "malloc failed !!!" << endl;
while(1);
}
cout << "malloc succeeded ~~~" << endl;
for(i = num - 10 ; i < num; i ++){
for( j = num - 10; j < num ; j++){
ls[i*num + j] = 1;
}
}
for(i = num - 11 ; i < num; i ++){
for( j = num - 11; j < num ; j++){
cout << ls[i*num + j] << endl;
}
}
return 0;
}
then I compile and run it. I get a "Segmentation fault".
How can I solve this?
The problem is, that your calculation
(num * num) * sizeof(float)
is done as 32-bit signed integer calculation and the result for num=56120 is
-4582051584
Which is then interpreted for size_t with a very huge value
18446744069127500032
You do not have so much memory ;) This is the reason why malloc() fails.
Cast num to size_t in the calculation of malloc, then it should work as expected.
As other have pointed out, 56120*56120 overflows int math on OP's platform. That is undefined behavior (UB).
malloc(size_t x) takes a size_t argument and the values passed to it is best calculated using at least size_t math. By reversing the multiplication order, this is accomplished. sizeof(float) * num cause num to be widened to at least size_t before the multiplication.
int num = 56120,i,j;
// ls = (float *)malloc((num * num)*sizeof(float));
ls = (float *) malloc(sizeof(float) * num * num);
Even though this prevents UB, This does not prevent overflow as mathematically sizeof(float)*56120*56120 may still exceed SIZE_MAX.
Code could detect potential overflow beforehand.
if (num < 0 || SIZE_MAX/sizeof(float)/num < num) Handle_Error();
No need to cast the result of malloc().
Using the size of the referenced variable is easier to code and maintain than sizing to the type.
When num == 0, malloc(0) == NULL is not necessarily an out-of-memory.
All together:
int num = 56120;
if (num < 0 || ((num > 0) && SIZE_MAX/(sizeof *ls)/num < num)) {
Handle_Error();
}
ls = malloc(sizeof *ls * num * num);
if (ls == NULL && num != 0) {
Handle_OOM();
}
int num = 56120,i,j;
ls = (float *)malloc((num * num)*sizeof(float));
num * num is 56120*56120 which is 3149454400 which overflows a signed int which causes undefined behavoir.
The reason 40000 works is that 40000*40000 is representable as an int.
Change the type of num to long long (or even unsigned int)
This is in contrast to what others have written, but for me, changing the variable num to size_t from int allows allocation. It could be that num*num overflows the int for malloc. Doing malloc with 56120 * 56120 instead of num*num should throw an overflow error.
float ls[3149454400]; is an array with automatic storage type, which is usually allocated on the process stack. A process stack is limited by default by a value much smaller than 12GB you are attempting to push there. So the segmentation fault you are observing is caused by the stack overflow, rather than by the malloc.
I am currently learning C++, so I am a beginner. I thought I'd make a small program to generate the Bessel polynomial terms. This is the program:
#include <iostream>
// x!
long long fact(const long long &x)
{
long long z {1};
for (long long i=1; i<=x; ++i)
z *= i;
return z;
}
// 2^n
long long pwr2(const int &n)
{
long long z {1};
for (long long i=0; i<n; ++i)
z *= 2;
return (n == 0 ? 1 : z);
}
// Bessel coefficients
long long bessel(long long *a, const long long &N)
{
for (long long i=0; i<=N; ++i)
a[i] = fact(N + i) / (pwr2(i) * fact(N - i) * fact(i));
return *a;
}
int main()
{
std::cout << "N = ";
long long N;
std::cin >> N;
long long *a {new long long[N + 1]};
*a = bessel(a, N);
for (long long i=0; i<=N; ++i)
std::cout << a[i] << ( i<N ? " " : "\n");
delete a;
a = nullptr;
return 0;
}
N=10 seems to be the limit. sizeof(long long) shows 8 (archlinux x64). fact(20) > (2^64)-1, so I'm stuck, even with long long. Is there a way to circumvent this limit?
The code, as you see it, is after I got desperate and modified all int to long long. I even added "ll" to all the numbers, there's no effect. I even removed the main parenthesis from the denominator and arranged the terms so that they divide, progressively, to somehow balance themselves, e.g.:
fact(N+i)/fact(N-i)/fact(i)/pwr2(i), also no effect.
You can't do what you want to with native types as they are limited by bit sizes.
However you can use some libraries to accomplish those (This is one such example) if you really need it (But as per your question , you are just learning c++ so I guess you dont need those)
I've written a C++ function to calculate factorial and used it to calculate 22C11 (Combination). I have declared a variable ans and set it to 0. I tried to calculate
22C11 = fact(2*n)/(fact(n)*fact(n))
where i sent n as 11. For some reason, i'm getting a negative value stored in answer. How can i fix this?
long int fact(long int n) {
if(n==1||n==0)
return 1;
long int x=1;
if(n>1)
x=n*fact(n-1);
return x;
}
The following lines are included in the main function:
long int ans=0;
ans=ans+(fact(2*n)/(fact(n)*fact(n)));
cout<<ans;
The answer i'm getting is -784
The correct answer should be 705432
NOTE: This function is working perfectly fine for n<=10. I have tried long long int instead of long int but it still isn't working.
It is unwise to actually calculate factorials - they grow extremely fast. Generally, with combinatorial formulae it's a good idea to look for a way to re-order operations to keep intermediate results somewhat constrained.
For example, let's look at (2*n)!/(n!*n!). It can be rewritten as ((n+1)*(n+2)*...*(2*n)) / (1*2*...*n) == (n+1)/1 * (n+2)/2 * (n+3)/3 ... * (2*n)/n. By interleaving multiplication and division, the rate of growth of intermediate result is reduced.
So, something like this:
int f(int n) {
int ret = 1;
for (int i = 1; i <= n; ++i) {
ret *= (n + i);
ret /= i;
}
return ret;
}
Demo
22! = 1,124,000,727,777,607,680,000
264 = 18,446,744,073,709,551,615
So unless you have 128-bit integers for unsigned long long you have integer overflow.
You are triggering integer overflow, which causes undefined behaviour. You could in fact use long long int, or unsigned long long int to get a little bit more precision, e.g:
unsigned long long fact(int n)
{
if(n < 2)
return 1;
return fact(n-1) * n;
}
You say you tried this and it didn't work but I'm guessing you forgot to also update the type of x or something. (In my version I removed x as it is redundant). And/or your calculation still was so big that it overflowed unsigned long long int.
You may be interested in this thread which shows an algorithm for working out nCr that doesn't require so much intermediate storage.
You increasing your chances of success by avoiding the brute force method.
COMB(N1, N2) = FACT(N1)/(FACT(N1-N2)*FACT(N2))
You can take advantage of the fact that both the nominator and the denominator have a lot of common terms.
COMB(N1, N2) = (N1-N2+1)*(N1-N2+2)*...*N1/FACT(N1)
Here's an implementation that makes use of that knowledge and computes COMB(22,11) with much less risk of integer overflow.
unsigned long long comb(int n1, int n2)
{
unsigned long long res = 1;
for (int i = (n1-n2)+1; i<= n1; ++i )
{
res *= i;
}
for (int i = 2; i<= n2; ++i )
{
res /= i;
}
return res;
}
I am doing a factorial program with strings because i need the factorial of Numbers greater than 250
I intent with:
string factorial(int n){
string fact="1";
for(int i=2; i<=n; i++){
b=atoi(fact)*n;
}
}
But the problem is that atoi not works. How can i convert my string in a integer.
And The most important Do I want to know if the program of this way will work with the factorial of 400 for example?
Not sure why you are trying to use string. Probably to save some space by not using integer vector? This is my solution by using integer vector to store factorial and print.Works well with 400 or any large number for that matter!
//Factorial of a big number
#include<iostream>
#include<vector>
using namespace std;
int main(){
int num;
cout<<"Enter the number :";
cin>>num;
vector<int> res;
res.push_back(1);
int carry=0;
for(int i=2;i<=num;i++){
for(int j=0;j<res.size();j++){
int tmp=res[j]*i;
res[j]=(tmp+carry)%10 ;
carry=(tmp+carry)/10;
}
while(carry!=0){
res.push_back(carry%10);
carry=carry/10;
}
}
for(int i=res.size()-1;i>=0;i--) cout<<res[i];
cout<<endl;
return 0;
}
Enter the number :400
Factorial of 400 :64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
There's a web site that will calculate factorials for you: http://www.nitrxgen.net/factorialcalc.php. It reports:
The resulting factorial of 250! is 493 digits long.
The result also contains 62 trailing zeroes (which constitutes to 12.58% of the whole number)
3232856260909107732320814552024368470994843717673780666747942427112823747555111209488817915371028199450928507353189432926730931712808990822791030279071281921676527240189264733218041186261006832925365133678939089569935713530175040513178760077247933065402339006164825552248819436572586057399222641254832982204849137721776650641276858807153128978777672951913990844377478702589172973255150283241787320658188482062478582659808848825548800000000000000000000000000000000000000000000000000000000000000
Many systems using C++ double only work up to 1E+308 or thereabouts; the value of 250! is too large to store in such numbers.
Consequently, you'll need to use some sort of multi-precision arithmetic library, either of your own devising using C++ string values, or using some other widely-used multi-precision library (GNU GMP for example).
The code below uses unsigned double long to calculate very large digits.
#include<iostream.h>
int main()
{
long k=1;
while(k!=0)
{
cout<<"\nLarge Factorial Calculator\n\n";
cout<<"Enter a number be calculated:";
cin>>k;
if (k<=33)
{
unsigned double long fact=1;
fact=1;
for(int b=k;b>=1;b--)
{
fact=fact*b;
}
cout<<"\nThe factorial of "<<k<<" is "<<fact<<"\n";
}
else
{
int numArr[10000];
int total,rem=0,count;
register int i;
//int i;
for(i=0;i<10000;i++)
numArr[i]=0;
numArr[10000]=1;
for(count=2;count<=k;count++)
{
while(i>0)
{
total=numArr[i]*count+rem;
rem=0;
if(total>9)
{
numArr[i]=total%10;
rem=total/10;
}
else
{
numArr[i]=total;
}
i--;
}
rem=0;
total=0;
i=10000;
}
cout<<"The factorial of "<<k<<" is \n\n";
for(i=0;i<10000;i++)
{
if(numArr[i]!=0 || count==1)
{
cout<<numArr[i];
count=1;
}
}
cout<<endl;
}
cout<<"\n\n";
}//while
return 0;
}
Output:
![Large Factorial Calculator
Enter a number be calculated:250
The factorial of 250 is
32328562609091077323208145520243684709948437176737806667479424271128237475551112
09488817915371028199450928507353189432926730931712808990822791030279071281921676
52724018926473321804118626100683292536513367893908956993571353017504051317876007
72479330654023390061648255522488194365725860573992226412548329822048491377217766
50641276858807153128978777672951913990844377478702589172973255150283241787320658
18848206247858265980884882554880000000000000000000000000000000000000000000000000
000000000000][1]
You can make atoi compile by adding c_str(), but it will be a long way to go till getting factorial. Currently you have no b around. And if you had, you still multiply int by int. So even if you eventually convert that to string before return, your range is still limited. Until you start to actually do multiplication with ASCII or use a bignum library there's no point to have string around.
Your factorial depends on conversion to int, which will overflow pretty fast, so you want be able to compute large factorials that way. To properly implement computation on big numbers you need to implement logic as for computation on paper, rules that you were tought in primary school, but treat long long ints as "atoms", not individual digits. And don't do it on strings, it would be painfully slow and full of nasty conversions
If you are going to solve factorial for numbers larger than around 12, you need a different approach than using atoi, since that just gives you a 32-bit integer, and no matter what you do, you are not going to get more than 2 billion (give or take) out of that. Even if you double the size of the number, you'll only get to about 20 or 21.
It's not that hard (relatively speaking) to write a string multiplication routine that takes a small(ish) number and multiplies each digit and ripples the results through to the the number (start from the back of the number, and fill it up).
Here's my obfuscated code - it is intentionally written such that you can't just take it and hand in as school homework, but it appears to work (matches the number in Jonathan Leffler's answer), and works up to (at least) 20000! [subject to enough memory].
std::string operator*(const std::string &s, int x)
{
int l = (int)s.length();
std::string r;
r.resize(l);
std::fill(r.begin(), r.end(), '0');
int b = 0;
int e = ~b;
const int c = 10;
for(int i = l+e; i != e;)
{
int d = (s[i]-0x30) * x, p = i + b;
while (d && p > e)
{
int t = r[p] - 0x30 + (d % c);
r[p] = (t % c) + 0x30;
d = t / c + d / c;
p--;
}
while (d)
{
r = static_cast<char>((d % c) +0x30)+r;
d /= c;
b++;
}
i--;
}
return r;
}
In C++, the largest integer type is 'long long', and it hold 64 bits of memory, so obviously you can't store 250! in an integer type. It is a clever idea to use strings, but what you are basically doing with your code is (I have never used the atoi() function, so I don't know if it even works with strings larger than 1 character, but it doesn't matter):
covert the string to integer (a string that if this code worked well, in one moment contains the value of 249!)
multiply the value of the string
So, after you are done multiplying, you don't even convert the integer back to string. And even if you did that, at one moment when you convert the string back to an integer, your program will crash, because the integer won't be able to hold the value of the string.
My suggestion is, to use some class for big integers. Unfortunately, there isn't one available in C++, so you'll have to code it by yourself or find one on the internet. But, don't worry, even if you code it by yourself, if you think a little, you'll see it's not that hard. You can even use your idea with the strings, which, even tough is not the best approach, for this problem, will still yield the results in the desired time not using too much memory.
This is a typical high precision problem.
You can use an array of unsigned long long instead of string.
like this:
struct node
{
unsigned long long digit[100000];
}
It should be faster than string.
But You still can use string unless you are urgent.
It may take you a few days to calculate 10000!.
I like use string because it is easy to write.
#include <bits/stdc++.h>
#pragma GCC optimize (2)
using namespace std;
const int MAXN = 90;
int n, m;
int a[MAXN];
string base[MAXN], f[MAXN][MAXN];
string sum, ans;
template <typename _T>
void Swap(_T &a, _T &b)
{
_T temp;
temp = a;
a = b;
b = temp;
}
string operator + (string s1, string s2)
{
string ret;
int digit, up = 0;
int len1 = s1.length(), len2 = s2.length();
if (len1 < len2) Swap(s1, s2), Swap(len1, len2);
while(len2 < len1) s2 = '0' + s2, len2++;
for (int i = len1 - 1; i >= 0; i--)
{
digit = s1[i] + s2[i] - '0' - '0' + up; up = 0;
if (digit >= 10) up = digit / 10, digit %= 10;
ret = char(digit + '0') + ret;
}
if (up) ret = char(up + '0') + ret;
return ret;
}
string operator * (string str, int p)
{
string ret = "0", f; int digit, mul;
int len = str.length();
for (int i = len - 1; i >= 0; i--)
{
f = "";
digit = str[i] - '0';
mul = p * digit;
while(mul)
{
digit = mul % 10 , mul /= 10;
f = char(digit + '0') + f;
}
for (int j = 1; j < len - i; j++) f = f + '0';
ret = ret + f;
}
return ret;
}
int main()
{
freopen("factorial.out", "w", stdout);
string ans = "1";
for (int i = 1; i <= 5000; i++)
{
ans = ans * i;
cout << i << "! = " << ans << endl;
}
return 0;
}
Actually, I know where the problem raised At the point where we multiply , there is the actual problem ,when numbers get multiplied and get bigger and bigger.
this code is tested and is giving the correct result.
#include <bits/stdc++.h>
using namespace std;
#define mod 72057594037927936 // 2^56 (17 digits)
// #define mod 18446744073709551616 // 2^64 (20 digits) Not supported
long long int prod_uint64(long long int x, long long int y)
{
return x * y % mod;
}
int main()
{
long long int n=14, s = 1;
while (n != 1)
{
s = prod_uint64(s , n) ;
n--;
}
}
Expexted output for 14! = 87178291200
The logic should be:
unsigned int factorial(int n)
{
unsigned int b=1;
for(int i=2; i<=n; i++){
b=b*n;
}
return b;
}
However b may get overflowed. So you may use a bigger integral type.
Or you can use float type which is inaccurate but can hold much bigger numbers.
But it seems none of the built-in types are big enough.