10^9 is way smaller than 2^32
So in your case, no need to use unsigned long long (it fits, yes), which is overkill and can lead to slower operation.
Use the proper type, normalized in stdint.h include: uint32_t or uint_least32_t (uint32_t vs uint_fast32_t vs uint_least32_t)
long is also guaranteed to be at least 32 bits, so it's a good & simple choice as well.
10^9 is way smaller than 2^32
So in your case, no need to use unsigned long long (it fits, yes), which is overkill and can lead to slower operation.
Use the proper type, normalized in stdint.h include: uint32_t or uint_least32_t (uint32_t vs uint_fast32_t vs uint_least32_t)
long is also guaranteed to be at least 32 bits, so it's a good & simple choice as well.
Yes it is (assuming that you are adopting the notation 10^9 to mean 1e9 - ^ is the XOR operator in C, and 10^9 is 3).
An unsigned long long has to be capable of storing a number between 0 and 264 - 1. Your maximum is much smaller than this.
Note also that an unsigned long has to be capable of storing a number between 0 and 232 - 1. Your maximum is also smaller than this.
numerical - Any way faster than pow() to compute an integer power of 10 in C++? - Stack Overflow
What is the range of int? - general - CodeChef Discuss
[C++] How should i work with 10^100 numbers ?
What is the range of a long long int and an int in powers of 10?
Something like this:
int quick_pow10(int n)
{
static int pow10[10] = {
1, 10, 100, 1000, 10000,
100000, 1000000, 10000000, 100000000, 1000000000
};
return pow10[n];
}
Obviously, can do the same thing for long long.
This should be several times faster than any competing method. However, it is quite limited if you have lots of bases (although the number of values goes down quite dramatically with larger bases), so if there isn't a huge number of combinations, it's still doable.
As a comparison:
#include <iostream>
#include <cstdlib>
#include <cmath>
static int quick_pow10(int n)
{
static int pow10[10] = {
1, 10, 100, 1000, 10000,
100000, 1000000, 10000000, 100000000, 1000000000
};
return pow10[n];
}
static int integer_pow(int x, int n)
{
int r = 1;
while (n--)
r *= x;
return r;
}
static int opt_int_pow(int n)
{
int r = 1;
const int x = 10;
while (n)
{
if (n & 1)
{
r *= x;
n--;
}
else
{
r *= x * x;
n -= 2;
}
}
return r;
}
int main(int argc, char **argv)
{
long long sum = 0;
int n = strtol(argv[1], 0, 0);
const long outer_loops = 1000000000;
if (argv[2][0] == 'a')
{
for(long i = 0; i < outer_loops / n; i++)
{
for(int j = 1; j < n+1; j++)
{
sum += quick_pow10(n);
}
}
}
if (argv[2][0] == 'b')
{
for(long i = 0; i < outer_loops / n; i++)
{
for(int j = 1; j < n+1; j++)
{
sum += integer_pow(10,n);
}
}
}
if (argv[2][0] == 'c')
{
for(long i = 0; i < outer_loops / n; i++)
{
for(int j = 1; j < n+1; j++)
{
sum += opt_int_pow(n);
}
}
}
std::cout << "sum=" << sum << std::endl;
return 0;
}
Compiled with g++ 4.6.3, using -Wall -O2 -std=c++0x, gives the following results:
$ g++ -Wall -O2 -std=c++0x pow.cpp
$ time ./a.out 8 a
sum=100000000000000000
real 0m0.124s
user 0m0.119s
sys 0m0.004s
$ time ./a.out 8 b
sum=100000000000000000
real 0m7.502s
user 0m7.482s
sys 0m0.003s
$ time ./a.out 8 c
sum=100000000000000000
real 0m6.098s
user 0m6.077s
sys 0m0.002s
(I did have an option for using pow as well, but it took 1m22.56s when I first tried it, so I removed it when I decided to have optimised loop variant)
There are certainly ways to compute integral powers of 10 faster than using std::pow()! The first realization is that pow(x, n) can be implemented in O(log n) time. The next realization is that pow(x, 10) is the same as (x << 3) * (x << 1). Of course, the compiler knows the latter, i.e., when you are multiplying an integer by the integer constant 10, the compiler will do whatever is fastest to multiply by 10. Based on these two rules it is easy to create fast computations, even if x is a big integer type.
In case you are interested in games like this:
- A generic O(log n) version of power is discussed in Elements of Programming.
- Lots of interesting "tricks" with integers are discussed in Hacker's Delight.
So, i went to a small competition my school organised and in one of the two problems i have been given i had 5 tests that had to be met, two with 232 - 1 (integer), one with 263 - 1 (i used long long double, it worked), and two with 10100 numbers.
Question is : How am i supposed to use these numbers if the largest numbers one can use in c++ are long long integers ? I have heard somebody mention writing the integer to a char array or something like that but i have no idea how you would create such a big array.
Edit : Problem : Given a number x, a number of n lines and 2 numbers a and b on each one of the n lines write a program to test ax+b=0 and return the line number where this condition is met.
This would be the rough equivalent of the problem (there was some roleplay, "NASA has given a number of n lines, bla,bla,bla" but this would be the "raw" version. As i said, a pretty simple problem but the 10100 part is problematic.
Edit 2 : Limitations - Dimension of source must be max. 20Kb and the running time must not exceed 0.1seconds
The minimum ranges you can rely on are:
short intandint: -32,767 to 32,767unsigned short intandunsigned int: 0 to 65,535long int: -2,147,483,647 to 2,147,483,647unsigned long int: 0 to 4,294,967,295
This means that no, long int cannot be relied upon to store any 10-digit number. However, a larger type, long long int, was introduced to C in C99 and C++ in C++11 (this type is also often supported as an extension by compilers built for older standards that did not include it). The minimum range for this type, if your compiler supports it, is:
long long int: -9,223,372,036,854,775,807 to 9,223,372,036,854,775,807unsigned long long int: 0 to 18,446,744,073,709,551,615
So that type will be big enough (again, if you have it available).
A note for those who believe I've made a mistake with these lower bounds: the C requirements for the ranges are written to allow for ones' complement or sign-magnitude integer representations, where the lowest representable value and the highest representable value differ only in sign. It is also allowed to have a two's complement representation where the value with sign bit 1 and all value bits 0 is a trap representation rather than a legal value. In other words, int is not required to be able to represent the value -32,768.
The size of the numerical types is not defined in the C++ standard, although the minimum sizes are. The way to tell what size they are on your platform is to use numeric limits
For example, the maximum value for a int can be found by:
std::numeric_limits<int>::max();
Computers don't work in base 10, which means that the maximum value will be in the form of 2n-1 because of how the numbers of represent in memory. Take for example eight bits (1 byte)
0100 1000
The right most bit (number) when set to 1 represents 20, the next bit 21, then 22 and so on until we get to the left most bit which if the number is unsigned represents 27.
So the number represents 26 + 23 = 64 + 8 = 72, because the 4th bit from the right and the 7th bit right the left are set.
If we set all values to 1:
11111111
The number is now (assuming unsigned)
128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255 = 28 - 1
And as we can see, that is the largest possible value that can be represented with 8 bits.
On my machine and int and a long are the same, each able to hold between -231 to 231 - 1. In my experience the most common size on modern 32 bit desktop machine.
Title says it all