I've programmed simple implementation of sieve of Eratosthenes for calculating primes in given range. Initially I planned to use long int as main integer type. Calculating all primes lesser then 10 milion took something between 11-12 seconds. But when I switched type to int, I was getting about 4-5 seconds instead. Therefore I wonder - why is it?
I understand that long int takes more space than int, but I'm running 64-bit CPU - so - if I understand correctly - it has ALU that accepts 64-bit integers i.e. instructions on such numbers can be executed in same number of cycles. My prior research revealed similar questions beeing asked about performance difference between unsigned and signed types ([here][1] or [here][2]), but I'm using signed variables and I still get performence drop for the same (lesser then 2^33-1) input. Below I post my full code.
#include <iostream>
#include <fstream>
int main()
{
unsigned long int X, i, j;
bool *prime, *primeFill;
std::fstream outFile;
clock_t T;
/* user interaction */
std::cout << "This applet will export all prime number from range (0, X). Enter desired X value: ";
std::cin >> X;
primeFill=new bool [X];
for (i=2; i<X; i++)
primeFill[i]=false;
prime = new bool [X];
/* main loop, where all actual computation happens */
T=clock(); i=2;
while(i<X) {
prime[i]=true, primeFill[i]=true;
for (j=2*i; j<=X; j+=i) prime[j]=false, primeFill[j]=true;
while (primeFill[i])
i++;
}
T=clock()-T;
/* outputing results to textfile & standard output */
outFile.open("primes.txt", std::ios::out);
for (i=2; i<X; i++)
if (prime[i])
outFile << i << '\n';
outFile.close();
std::cout << "Finished. Computation took " << (1000*float(T)) / CLOCKS_PER_SEC << " ms\n";
return 0;
}
EDIT New code above doesn't produce such problem. Refer to my answer below.
As #LogicStuff correctly pointed out, I missed the point of Sieve of Eratosthenes by using isPrime() function. I've edited the code (edited original question) and now the same test (calculating primes lesser than 10 milion) takes between 250 and 300 miliseconds despite integer type - I've tested int, long int, unsigned int and unsigned long int.
This means that source of the problem was inside isPrime() function i.e. compilier or CPU lack either optimalization for double conversion or % operator. I'm betting on the first one, because such problem was described here for unsigned int as I mentioned in initial post. Thanks for all comments.
Here is the problem, Project Euler #45
And here's the code I wrote for it:
#include <iostream>
#include <math.h>
using namespace std;
bool ispent (long num){
long double x = (sqrt(24*num+1) + 1.0)/6.0;
if (floor(x)==x) return true;
else return false;
}
bool ishex (long num){
long double x = (sqrt(8*num+1) + 1.0)/4.0;
if (floor(x)==x) return true;
else return false;
}
int main(){
int i=286;
while(true){
long x = (i*(i+1))/2;
if((ispent(x)) && (ishex(x))){
cout << x;
break;
}
i++;
}
}
This gives the output 40755, whereas I require the next number. What could be the possible bug?
The issue is that using square roots to check if a number is pentagonal or hexagonal is imprecise, so the test will fail and you will overflow x.
To fix this, you can use a type with more precision, like replacing long with unsigned long, or even unsigned long long.
You are overflowing the 32-bit representation of x. If you know the next x is 1533776805, then an intermediate value of 2x is necessary, which at 3e9 overflows a signed integer. You can just fit this in an unsigned int, but I would use a 64-bit integer instead. #include <stdint.h>, and use int64_t for both i and x. But I agree with the other commenters, there's something suspicious about testing for exact double precision answers
I was looking through C++ Integer Overflow and Promotion, tried to replicate it, and finally ended up with this:
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
int i = -15;
unsigned int j = 10;
cout << i+j << endl; // 4294967291
printf("%d\n", i+j); // -5 (!)
printf("%u\n", i+j); // 4294967291
return 0;
}
The cout does what I expected after reading the post mentioned above, as does the second printf: both print 4294967291. The first printf, however, prints -5. Now, my guess is that this is printf simply interpreting the unsigned value of 4294967291 as a signed value, ending up with -5 (which would fit seeing that the 2's complement of 4294967291 is 11...11011), but I'm not 100% convinced that I did not overlook anything. So, am I right or is something else happening here?
Yes, you got it right. That's why printf() is generally unsafe: it interprets its arguments strictly according to the format string, ignoring their actual type.
We know that
sin(x)=x-x^3/3!+x^5/5!-x^7/7!+x^9/9! and so on. I have written this code:
#include <iostream>
#include <math.h>
using namespace std;
const int m=19;
int factorial(int n) {
if (n==0){ return 1;}
return n*factorial(n-1);
}
int main() {
float x;
cin >> x;
float sum=0;
int k=1;
for (int i=1;i<=m;i+=2) {
sum+=(k*(powf(x,i)/factorial(i)));
k=k*(-1);
}
cout<<"series sum is equal :"<<sum<<endl;
return 0;
}
One problem is that when I enter x=3 it gives me -10.9136, but I know that values range of sin(x) is [-1, 1] what is problem? Please help me.
The problem is that you're running out of precision due to destructive cancellation.
You have an alternating series where some of the terms get very large. But those terms cancel each other out to a small result. Since float has limited precision, your round off error is larger than your final value.
You can "reduce" the problem by using double-precision. But it won't go away. Standard implementations of sin/cos involve taking the modulo of the argument by 2 pi to make it small.
EDIT :
I found the other problem. You have an integer overflow in your factorial function when i = 19.
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