Division between a large numbers (Above long long) and a single integer - c++

I am trying to divide a number by an integer as suggested in the title, and i am having a hard time doing so. I was thinking about inserting the big number's digits into a vector then repeatedly substracting said digit from the vector until it is null. However, i cannot find the code to do it. Here is what i have been trying so far:
#include <fstream>
using namespace std;
int v[100],r[100]; //In v i store the initial number,in r i store the result
int main()
{
FILE*fin=fopen("imp.in","r");
FILE*fout=fopen("imp.out","w");
int n,x,c,w,k,m=2;
fscanf(fin,"%d",&n); //Reads the number of digits the number has
for(;n>0;--n)
{
fscanf(fin,"%d",&x);
v[n]=x;
}
fscanf(fin,"%d",&c); //Reads the digit it has to be divided by
while(v[n]!=0)
{
k=0;
while(v[1]>=c)
{
v[1]-=c;
++k;
}//As long as the first position in vector can be substracted, increase k
--v[2];
v[1]+=10;
/* Because first position will be negative, take one from second position and add ten in the first*/
w=2;
while(v[w]<0)
{
v[w]=9;
--v[w+1];
++w;
}
/*When, for example, you substract one from 1000,it will become 999. This loop helps do that*/
r[1]+=k;
if(r[1]>9)
{
r[1]-=10;
w=2;
++r[2];
while(r[w]>9)
{
++r[w+1];
r[w]=0;
++w;
if(w>m)m=w;
}
}
/*If statement and the line of code above it inserts the result into r[100]*/
}
for(;w>0;--w)fprintf(fout,"%d",r[w]);
return 0;
}

You can use GMP rather than write it yourself from scratch. It will take you less time to download the GMP sources, build it, and learn how to use it, than to write it yourself.
Pencil and paper division in base 2^32, or 2^64, would be a lot more efficient than "division by subtraction" and I believe that GMP employs a better algorithm than that.
With GMP you'd write:
mpz_class a("134897563047067890568704560457984059182035823590780968094759123590346040967804956029586405960249562895760983475187459073406984560900123895702851034560016405716045613495619456196450196450165901268051620465016405634056104951923845902387581");
std::cout << a / 7 << std::endl;

Related

How do I make the console print things one at a time in C++ the way Java and Python do?

I'm trying to get a feel for C++ by creating a program to efficiently find highly composite numbers, but I'm facing an inconvenience. The console waits and then prints everything at once. I want it to print things one at a time like Java and Python do. How do I do that?
Here's the code:
#include <iostream>
int main(){
int record=0; //Highest number of factors found in a number so far
for(int n=1; n<2147483647; n++){
int factors=1;
for(int PPF=2; PPF<=n; PPF++){ //PPF="Possible Prime Factor"
bool isPrime=true;
for(int i=2; i<PPF; i++){ //
if(PPF%i==0){ //Determining if the PPF is prime
isPrime=false; //
break;
}
}
if(isPrime){
if(n%PPF==0){ //Here is where I calculate the number of factors n has based on its prime factorization.
int PRP=1; //PRP="Prime Raised to Power"
int pow;
for(pow=1; n%(PRP*PPF)==0; pow++){ //Finding the exponent of a specific prime factor
PRP*=PPF;
}
factors*=pow;
}else{
break;
}
}
}
if(factors>record){
record=factors;
std::cout<<n; //Print the highly composite number
printf("\n"); //Gotta make a new line the old-fashioned way cuz this is a low-level language
}
}
}
I'm running this on VS Code with CodeRunner and all the necessary C/C++ extensions.
More precisely, you need std::flush. std::endl prints a line break and flushes, but flush does so without the break. You can also print to std::cerr which is not buffered and prints everything directly.

Why by using n&(n-1) is not able to calculate number of 1's bits?

I found a video on youtube that says by using n&(n-1) we can able to count number of 1's bits and it's much faster than - right shifting the bits by one and then checking the last bit . When I wrote the code using this method to calculate number of bits it's giving output as 9 instead of 3 - if we 01011 as parameter.
I debug the program and not able to find why it's happening so ?I am confused when in while loop condition , both A and A-1 is 512, it get out of loop even A&(A-1) = 1000000000 not 0 (zero).
If anyone knows what I am missing please let me know .
#include <iostream>
using namespace std;
int bits(unsigned int A){
int counter=0;
unsigned int t;
while (A&(A-1))
{
counter++;
A--;
}
return counter;
}
int main()
{
unsigned int A=01011;
int res=bits(A);
cout<<"Result is "<<res<<"\n";
return 0;
}
Thanking You
Yours Truly,
Rishabh Raghwendra
This is the Kerningham trick to calculate the number of bits without shifting. (Original author precedes Kerningham by a decade, but mr K popularised it).
n&(n-1) peels off the least significant one, meaning that one should write the result back to n.
while (n) {
++counter;
n&=n-1;
}

Inconsistency with std::cout - failing to print on specific numbers

I'm running a program to factorise a large number, which outputs each factor it finds as it goes through, smallest to largest. It works fine for numbers below the 1 billion mark, as far as I have tested, but I get a very strange bug when I input 1185914148403 to the program - the factor of 311 will not print.The modulus division returns 0, and it enters the inner while loop, but it won't print 311 unless I explicitly check for that case. For low values, like 622, 311 prints just fine, but here, the smaller factors print, and everything except the printing works fine, and yet nothing is printed. What could possibly be going on?
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
void nextPrime(std::vector<long long>& primes);
int main(int argc,char* argv[])
{
int startTime=clock();
long long num=std::stol(argv[1]);
long long largest=1;
std::vector<long long>primes;
primes.push_back(2);
while(1) //iterate through the prime list, divide the num down as far as pos - done when num=1
{
long long prime=primes[primes.size()-1]; //the largest prime, the one we care about
while(!(num%prime)) //while that prime divides, divide down
{
num/=prime;
largest=prime;
std::cout<<std::endl<<prime;
if(prime==311)
{
//std::cout<<std::endl<<prime;
}
}
if(num==1) //once we divide down by the largest prime factor, it'll hit 1, and we're done
{
break;
}
nextPrime(primes);
long long newPrime=primes[primes.size()-1];
if(newPrime>num)
{
break;
}
}
int endTime=clock();
double timeTaken=(endTime-startTime)/double(CLOCKS_PER_SEC);
std::cout<<"\nThat took "<<timeTaken<<" seconds\n";
std::cout<<"The largest prime factor of "<<std::stol(argv[1])<<" is "<<largest<<"\n";
}
void nextPrime(std::vector<long long>& primes)
{
long long largest=primes[primes.size()-1];
long long maybe=largest+1;
long long pt=0;
while(1)//check all the primes up to sqrt of the maybe-prime
{
long long prime=primes[pt];
if(prime*prime>maybe)
{
primes.push_back(maybe);
return;
}
if(!(maybe%prime)) //if the prime is a factor, it's not prime-try next, and go back to 1st prime
{
maybe++;
pt=0;
continue;
}
else //if not, check the next prime
{
pt++;
}
}
}
You write:
std::cout<<std::endl<<prime;
Maybe you meant:
std::cout << prime << std::endl;
This will print the prime and then flush the output. For the number 1185914148403, there is an early factor 311 and then no more factors for a while.
Your algorithm is very slow and takes a long time before it finds any other factor. Since you did not flush the output after outputting the first 311, then depending on your compiler, you may not have that number appear on screen for a very long time.
As noted in comments, std::stol returns a long, however your program works with long long. Since you did not get an out-of-range exception thrown, this indicates that you are on a system where long is 64-bit. But it would be good to fix this anyway and use std::stoll.

C++ Handling big numbers

Okay, I have to do simple task for my c++ class. Two functions, first is Fibonacci sequence, second some random sequence (finding e). It looks like this:
#include <stdio.h>
#include <cstdlib>
#include <string>
#include <math.h>
void fib(int number)
{
int a=0, b=1;
printf("%d\n", a);
for (; number>0; number--)
{
printf("%d\n", b);
b+=a;
a = b-a;
}
}
void e_math(unsigned int number)
{
for (double n = 1; number>0; number--, n++)
{
printf("%f\n", pow((1+1/n), n));
}
}
int main(int argc, char** argv)
{
if (std::string(argv[2])=="f") fib(atoi(argv[1])-1);
if (std::string(argv[2])=="c") e_math(atoi(argv[1])-1);
else printf("Bad argument\n");
}
So at the end I did g++ main.cpp -o app;./app 10 f. It worked perfectly. But when I thought: Hmm, maybe lets check for bigger number, and added 50 it just messed up. I mean it did good for about 40 sequence numbers (checked with Python), but then it started to printf() negatives etc. I figured it's probably about int range. So I changed int a=0, b=1 to long long a=0, b=1, but still it prints the same (I still use printf("%d..), because %lld does not work
There are information in comments telling you how to be able to print long long correctly so that you can benefit from the whole range. However, as said blazs in his answer, you will not go much further (it will cycle for n=94 on unsigned 64 bits).
If you want to handle much bigger Fibonacci numbers (in fact, arbitrary large numbers) you can use boost::multiprecision.
For example:
#include <boost/multiprecision/gmp.hpp>
boost::multiprecision::mpz_int fib(boost::multiprecision::mpz_int number)
{
boost::multiprecision::mpz_int a=0, b=1;
for (; number>0; number--)
{
b += a;
a = b-a;
}
return a;
}
int main()
{
std::cout << fib(500);
}
You'll need to link with gmp when building. For example:
g++ -o fib fib.cc -lgmp
./fib
139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125
The nth Fibonacci number is around 1.6^n which for n=50 is a big number (it's 53316291173). You may be able to represnet it as long, but as the thing grows exponentially, you won't be able to store Fn for large n into a primitive data type (where Fn denotes the nth Fibonacci number): the n+1th Fibonacci number is roughly 1.6 times the nth Fibonacci number.
You need a big int data type to compute Fn for large n.
You can use Integer classes from The GNU Multiple Precision Arithmetic Library. Here the link to the C++ Interface.
Edit: Also look at 15.7.4 Fibonacci Numbers.
Since %lld is not portable and does not work in any compiler, what about if you declare a and b as long and print the result with c++ std::cout?
This is necessary since the 50th Fibonacci number is 7778742049, which is bigger than the typical max positive integer value (32 bits) that is 2147483647.
By the way, you should remove the last else, I don't think is doing what you want when the parameter f is provided.
Here is the code working.

Online judge Rejecting My Answer

The Next Palindrome
The below code is the solution to this problem
A positive integer is called a palindrome if its representation in the decimal system is the same when read from left to right and from right to left. For a given positive integer K of not more than 1000000 digits, write the value of the smallest palindrome larger than K to output. Numbers are always displayed without leading zeros.
Input
The first line contains integer t, the number of test cases. Integers K are given in the next t lines.
Output
For each K, output the smallest palindrome larger than K.
Example
Input:
2
808
2133
Output:
818
2222
#include <iostream>
using namespace std;
int main()
{
long t;
cin>>t;
long a[t],k;
for(long i=0;i<t;++i)
{
cin>>k;
a[i]=k;
}
for(long i=0;i<t;++i)
{
long palin=0,num;
palin=a[i];
num=palin+1;
while(1)
{
long x=0,rev=0,ans=num;
do
{
x=ans%10;
rev=rev*10+x;
ans=ans/10;
}while(ans);
if(rev==num)
{
cout<<"\n"<<rev<<"\n";
break;
}
else
++num;
}
}
return 0;
}
The code is giving me expected output, I even made changes in the code making the variable K and t to LONG, should i make them long long instead of long, or is there any issue with my logic ...?
You can write a effective program by using a string instead of long. I have used it. Here I am giving the code:
#include<iostream>
using namespace std;
#include<string.h>
int main()
{
char s[80]; //you can take any big index instead 80
gets(s);
int a=0,l=strlen(s);
for(int i=0;i<l;i++) {
if(s[i]==s[l-i]) {
a++;
}
}
if(a==l) {
cout<<"Number is palindrome";
}
else {
cout<<"Number is not palindrome";
}
return(0);
}
Is the task really to handle integers up to 1,000,000 digits? Or is the input smaller than 1M?
"long" is guaranteed to be at least 32 bits long (so an unsigned long can hold integers [0, 4,294,967,295]. So if your input is < 1M, your safe with just regular long.
"long long" is guaranteed to be at least 64 bits long, so the range for unsigned long long is [0, 18x10^18]. Larger than 4M but still much smaller than 1M decimal digits.
Another issue with your code is the fact that it looks like your trying to dynamically allocate a stack array.
cin>>t;
long a[t],k;
You can't provide a variable as the array size. This is a very basic point an C++, and you must do one of the following:
Use a constant compile-time maximum size for the array (simplest solution).
#define A_MAX_SIZE 100
long a[A_MAX_SIZE];
Use a dynamic array (but then you must allocated and delete it later).
See link: http://www.cplusplus.com/doc/tutorial/dynamic/
Use an STL container that will take care of memory for you.
For example: http://www.cplusplus.com/reference/stl/vector/vector/