I am a beginner in C++, and I just finished reading chapter 1 of the C++ Primer. So I try the problem of computing the largest prime factor, and I find out that my program works well up to a number of sizes 10e9 but fails after that e.g.600851475143 as it always returns a wired number e.g.2147483647 when I feed any large number into it. I know a similar question has been asked many times, I just wonder why this could happen to me. Thanks in advance.
P.S. I guess the reason has to do with some part of my program that is not capable to handle some large number.
#include <iostream>
int main()
{
int val = 0, temp = 0;
std::cout << "Please enter: " << std::endl;
std::cin >> val;
for (int num = 0; num != 1; val = num){
num = val/2;
temp = val;
while (val%num != 0)
--num;
}
std::cout << temp << std::endl;
return 0;
}
Your int type is 32 bits (like on most systems). The largest value a two's complement signed 32 bit value can store is 2 ** 31 - 1, or 2147483647. Take a look at man limits.h if you want to know the constants defining the limits of your types, and/or use larger types (e.g. unsigned would double your range at basically no cost, uint64_t from stdint.h/inttypes.h would expand it by a factor of 8.4 billion and only cost something meaningful on 32 bit systems).
2147483647 isn't a wired number its INT_MAX which is defined in climits header file. This happens when you reach maximum capacity of an int.
You can use a bigger data type such as std::size_t or unsigned long long int, for that purpose, which have a maximum value of 18446744073709551615.
I am trying to calculate the combination C(40, 20) in C++, however the data types in C++ seems unable to correctly handle this calculation even though I have used long long data type. The following is my code:
#include <iostream>
long long fac(int x) {
register long long i,f = 1; // Optimize with regFunction
for(i = 1;i <= x;i++)
f *= i;
std::cout << f << std::endl;
return f;
}
// C(n,r) = n!/r!(n-r)!
long long C(long long n, long long r) {
return fac(n) / (fac(r) * fac(n - r));
}
int main(int argc, char const *argv[]) {
std::cout << C(40, 20) << std::endl;
return 0;
}
Any idea to solve this problem?
Compute C at once by executing division immediately after multiplication:
long long C(long long n, long long r)
{
long long f = 1; // Optimize with regFunction
for(auto i = 0; i < r;i++)
f = (f * (n - i)) / (i + 1);
return f ;
}
Result should be exact (divisions without remainders, until overflows) since any integer factor present in (i+1) is already present in (n -i). (Should not be too difficult to prove)
Your numbers are growing too much and that is a common problem in this kind of calculations and I am afraid there is no straightforward solution. Even if you might reduce a bit the number of multiplications you will make probably still you will end up in an overflow with long long
You might want to check those out:
https://mattmccutchen.net/bigint/
https://gmplib.org/
I know there are different algorithmic approaches on this matter. I remember there were some solutions to use strings to store integer representations and stuff but as #Konrad mentioned this might be a poor approach to the matter.
The problem is that factorials get big very quickly. 40! is too large to be stored in a long long. Luckily you don’t actually need to compute this number here since you can reduce the fraction in the calculation of C(n, r) before computing it. This yields the equation (from Wikipedia):
This works much better since k! (r! in your code) is a much smaller number than n!. However, at some point it will also break down.
Alternatively, you can also use the recurrence definition by implementing a recursive algorithm. However, this will be very inefficient (exponential running time) unless you memoise intermediate results.
A lazy way out would be to use a library that supports multiple precision, for example GNU GMP.
Once you have installed it correctly (available from the repositories on most Linux distributions), it comes down to:
adding #include <gmpxx.h> to your source file
replacing long long with mpz_class
compiling with -lgmpxx -lgmp
The source:
#include <iostream>
#include <gmpxx.h>
mpz_class fac(mpz_class x) {
int i;
mpz_class f(1); // Optimize with regFunction
for(i = 1;i <= x;i++)
f *= i;
std::cout << f << std::endl;
return f;
}
// C(n,r) = n!/r!(n-r)!
mpz_class C(mpz_class n, mpz_class r) {
return fac(n) / (fac(r) * fac(n - r));
}
int main(int argc, char const *argv[]) {
std::cout << C(40, 20) << std::endl;
return 0;
}
Compiling and running:
$ g++ comb.cpp -lgmpxx -lgmp -o comb
$ ./comb
2432902008176640000
2432902008176640000
815915283247897734345611269596115894272000000000
137846528820
If you want to be thorough, you can do a lot more, but this will get you answers.
Even if you used uint64 aka ulonglong, the max value is 18446744073709551615 whereas 40! is 815915283247897734345611269596115894272000000000 which is a bit bigger.
I recommend you to use GMP for this kind of maths
I'm trying to predict numbers generated by C++ rand() function. Here's a link to the code, it possibly uses: click
And here's my code that emulates rand():
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(0));
unsigned a = rand();
unsigned b = rand();
cout << (a * 1103515245U + 12345U) % 0x7fffffffU << '\n';
cout << b << '\n'; // they should match, right? But they don't...
return 0;
}
Why doesn't my value match b?
The glibc only uses the old linear congruential generator if the TYPE_0 generator is chosen, as you can see in the code you linked. (By default, it uses the TYPE_3 generator.) This is the only case if the RNG buffer is 8 bytes large. You can force the old behavior with initstate:
char state[8];
initstate(time(0), state, 8);
unsigned a = rand();
unsigned b = rand();
cout << (a * 1103515245u + 12345u) % 0x7fffffffu << '\n';
Then you often get the same numbers, and when you don't, it's only offset by one. I haven't, at a cursory glance, been able to figure precisely why that difference happens (may edit later), but I suspect carry bit shenanigans.
EDIT: Okay, I figured it out. glibc's rand uses signed arithmetic inside, and it uses & rather than % for the modulus. This makes the one-bit difference if (a * 1103515245 + 12345) becomes negative. If you write
int a = rand();
int b = rand();
cout << (a * 1103515245 + 12345) & 0x7fffffff << '\n';
then you get the same results all the time. Well, really a and b should be int32_t for maximum portability, but I suspect that's not a concern here. Because library internals and portability is kind of a lost cause, anyway.
Adding to Wintermute's response: By default, it uses the TYPE_3 generator.
I try
long long int l = 42343254325322343224;
but to no avail. Why does it tell me, "integer constant is too long." I am using the long long int type which should be able to hold more than 19 digits. Am I doing something wrong here or is there a special secret I do not know of just yet?
Because it's more, on my x86_64 system, of 2^64
// 42343254325322343224
// maximum for 8 byte long long int (2^64) 18446744073709551616
// (2^64-1 maximum unsigned representable)
std::cout << sizeof(long long int); // 8
you shouldn't confuse the number of digits with the number of bits necessary to represent a number
Take a look at Boost.Multiprecision at Boost.Multiprecision
It defines templates and classes to handle larger numbers.
Here is the example from the Boost tutorial:
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
int128_t v = 1;
// Do some fixed precision arithmetic:
for(unsigned i = 1; i <= 20; ++i)
v *= i;
std::cout << v << std::endl; // prints 20!
// Repeat at arbitrary precision:
cpp_int u = 1;
for(unsigned i = 1; i <= 100; ++i)
u *= i;
std::cout << u << std::endl; // prints 100!
It seems that the value of the integer literal exceeds the acceptable value for type long long int
Try the following program that to determine maximum values of types long long int and unsigned long long int
#include <iostream>
#include <limits>
int main()
{
std::cout << std::numeric_limits<long long int>::max() << std::endl;
std::cout << std::numeric_limits<unsigned long long int>::max() << std::endl;
return 0;
}
I have gotten the following results at www.ideone.com
9223372036854775807
18446744073709551615
You can compare it with the value you specified
42343254325322343224
Take into account that in general case there is no need to specify suffix ll for a integer decimal literal that is so big that can be stored only in type long long int The compiler itself will determine the most appropriate type ( int or long int or long long int ) for the integral decimal literal.
How do I raise a number to a power?
2^1
2^2
2^3
etc...
pow() in the cmath library. More info here.
Don't forget to put #include<cmath> at the top of the file.
std::pow in the <cmath> header has these overloads:
pow(float, float);
pow(float, int);
pow(double, double); // taken over from C
pow(double, int);
pow(long double, long double);
pow(long double, int);
Now you can't just do
pow(2, N)
with N being an int, because it doesn't know which of float, double, or long double version it should take, and you would get an ambiguity error. All three would need a conversion from int to floating point, and all three are equally costly!
Therefore, be sure to have the first argument typed so it matches one of those three perfectly. I usually use double
pow(2.0, N)
Some lawyer crap from me again. I've often fallen in this pitfall myself, so I'm going to warn you about it.
In C++ the "^" operator is a bitwise XOR. It does not work for raising to a power. The x << n is a left shift of the binary number which is the same as multiplying x by 2 n number of times and that can only be used when raising 2 to a power, and not other integers. The POW function is a math function that will work generically.
You should be able to use normal C methods in math.
#include <cmath>
pow(2,3)
if you're on a unix-like system, man cmath
Is that what you're asking?
Sujal
Use the pow(x,y) function: See Here
Just include math.h and you're all set.
While pow( base, exp ) is a great suggestion, be aware that it typically works in floating-point.
This may or may not be what you want: on some systems a simple loop multiplying on an accumulator will be faster for integer types.
And for square specifically, you might as well just multiply the numbers together yourself, floating-point or integer; it's not really a decrease in readability (IMHO) and you avoid the performance overhead of a function call.
I don't have enough reputation to comment, but if you like working with QT, they have their own version.
#include <QtCore/qmath.h>
qPow(x, y); // returns x raised to the y power.
Or if you aren't using QT, cmath has basically the same thing.
#include <cmath>
double x = 5, y = 7; //As an example, 5 ^ 7 = 78125
pow(x, y); //Should return this: 78125
if you want to deal with base_2 only then i recommend using left shift operator << instead of math library.
sample code :
int exp = 16;
for(int base_2 = 1; base_2 < (1 << exp); (base_2 <<= 1)){
std::cout << base_2 << std::endl;
}
sample output :
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768
It's pow or powf in <math.h>
There is no special infix operator like in Visual Basic or Python
#include <iostream>
#include <conio.h>
using namespace std;
double raiseToPow(double ,int) //raiseToPow variable of type double which takes arguments (double, int)
void main()
{
double x; //initializing the variable x and i
int i;
cout<<"please enter the number";
cin>>x;
cout<<"plese enter the integer power that you want this number raised to";
cin>>i;
cout<<x<<"raise to power"<<i<<"is equal to"<<raiseToPow(x,i);
}
//definition of the function raiseToPower
double raiseToPow(double x, int power)
{
double result;
int i;
result =1.0;
for (i=1, i<=power;i++)
{
result = result*x;
}
return(result);
}
Many answers have suggested pow() or similar alternatives or their own implementations. However, given the examples (2^1, 2^2 and 2^3) in your question, I would guess whether you only need to raise 2 to an integer power. If this is the case, I would suggest you to use 1 << n for 2^n.
pow(2.0,1.0)
pow(2.0,2.0)
pow(2.0,3.0)
Your original question title is misleading. To just square, use 2*2.
First add #include <cmath> then
you can use pow methode in your code for example :
pow(3.5, 3);
Which 3.5 is base and 3 is exp
Note that the use of pow(x,y) is less efficient than x*x*x y times as shown and answered here https://stackoverflow.com/a/2940800/319728.
So if you're going for efficiency use x*x*x.
I am using the library cmath or math.h in order to make use of the pow() library functions that takes care of the powers
#include<iostream>
#include<cmath>
int main()
{
double number,power, result;
cout<<"\nEnter the number to raise to power: ";
cin>>number;
cout<<"\nEnter the power to raise to: ";
cin>>power;
result = pow(number,power);
cout<<"\n"<< number <<"^"<< power<<" = "<< result;
return 0;
}
use pow() function in cmath, tgmath or math.h library.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout << pow(a,b) << endl; // this calculates a^b
return 0;
}
do note that if you give input to power as any data type other than long double then the answer will be promoted to that of double. that is it will take input and give output as double. for long double inputs the return type is long double. for changing the answer to int use,
int c=(int)pow(a,b)
But, do keep in mind for some numbers this may result in a number less than the correct answer. so for example you have to calculate 5^2, then the answer can be returned as 24.99999999999 on some compilers. on changing the data type to int the answer will be 24 rather than 25 the correct answer. So, do this
int c=(int)(pow(a,b)+0.5)
Now, your answer will be correct.
also, for very large numbers data is lost in changing data type double to long long int.
for example you write
long long int c=(long long int)(pow(a,b)+0.5);
and give input a=3 and b=38
then the result will come out to be 1350851717672992000 while the correct answer is 1350851717672992089, this happens because pow() function return 1.35085e+18 which gets promoted to int as 1350851717672992000. I suggest writing a custom power function for such scenarios, like:-
long long int __pow (long long int a, long long int b)
{
long long int q=1;
for (long long int i=0;i<=b-1;i++)
{
q=q*a;
}
return q;
}
and then calling it whenever you want like,
int main()
{
long long int a,b;
cin >> a >> b;
long long int c=__pow(a,b);
cout << c << endl;
return 0;
}
For numbers greater than the range of long long int, either use boost library or strings.
int power (int i, int ow) // works only for ow >= 1
{ // but does not require <cmath> library!=)
if (ow > 1)
{
i = i * power (i, ow - 1);
}
return i;
}
cout << power(6,7); //you can enter variables here