I know from previous threads on this topic that using float arithmetic causes precision anomalies. But Interestingly I observed that the same function is behaving in two different ways.Using COUT output is 4 but if I am saving the result into a variable, then result is 3!
#include <iostream>
#include <cmath>
using namespace std;
#define mod 1000000007
long long int fastPower(long long int a, int n){
long long int res = 1;
while (n) {
if (n & 1) res = (res * a) % mod;
n >>= 1; a = (a * a) % mod;
}
return res;
}
int main() {
int j = 3;
cout << pow(64, (double)1.0/(double)j) << endl; // Outputs 4
int root = pow(64, (double)1.0/(double)j);
cout << root << endl; // Outputs 3
/* As said by "pts", i tried including this condition in my code but including this line in my code resulted in TimeLimitExceeded(TLE). */
if (fastPower(root+1,j) <= 64) root++;
cout << root << endl; // Outputs 4 :)
return 0;
}
Code output on Ideone.com
Now, how can we avoid such errors in a programing contest.
I do not want to use 'round' function because I need only integer value of root. i.e
63(1/6) = 1, 20(1/2) = 4, etc...
How should I modify my code so that correct result is stored in the root variable.
pow returns double. When cout is used, it is rounded(thus, it is 4). When you cast it to int, it just truncates fractional part. Pow returns something like 4 - eps(because of precision issues). When it is just truncated, it is equal to 3.
Dirty hack useful in programming contests: int root = (int)(pow(...) + 1e-7)
As far as I know, there is no single-line answer in C and C++ for getting the ath root of b rounded down.
As a quick workaround, you can do something like:
int root(int a, int b) {
return floor(pow(b, 1.0 / a) + 0.001);
}
This doesn't work for every value, but by adjusting the constant (0.001), you may get lucky and it would work for the test input.
As a workaround, use pow as you use it already, and if it returns r, then try r - 1, r and r + 1 by multiplying it back (using fast exponentiation of integers). This will work most of the time.
If you need a solution which works 100% of the time, then don't use floating point numbers. Use for example binary search with exponentiation. There are faster algorithms (such as Newton iteration), but if you use them on integers then you need to write custom logic to find the exact solution as soon as they stop converging.
There are two problems with your program:
The pow(int, int) overload is no longer available. To avoid this problem, cast the first parameter to double, float, or long double.
Also, command of cout is rounding off your answer in upper roof (3.something into 4) and saving your data is removing all the decimal part and is accepting only integer part.
Related
Say I have a number, 100000, I can use some simple maths to check its size, i.e. log(100000) -> 5 (base 10 logarithm). Theres also another way of doing this, which is quite slow. std::string num = std::to_string(100000), num.size(). Is there an way to mathematically determine the length of a number? (not just 100000, but for things like 2313455, 123876132.. etc)
Why not use ceil? It rounds up to the nearest whole number - you can just wrap that around your log function, and add a check afterwards to catch the fact that a power of 10 would return 1 less than expected.
Here is a solution to the problem using single precision floating point numbers in O(1):
#include <cstdio>
#include <iostream>
#include <cstring>
int main(){
float x = 500; // to be converted
uint32_t f;
std::memcpy(&f, &x, sizeof(uint32_t)); // Convert float into a manageable int
uint8_t exp = (f & (0b11111111 << 23)) >> 23; // get the exponent
exp -= 127; // floating point bias
exp /= 3.32; // This will round but for this case it should be fine (ln2(10))
std::cout << std::to_string(exp) << std::endl;
}
For a number in scientific notation a*10^e this will return e (when 1<=a<10), so the length of the number (if it has an absolute value larger than 1), will be exp + 1.
For double precision this works, but you have to adapt it (bias is 1023 I think, and bit alignment is different. Check this)
This only works for floating point numbers, though so probably not very useful in this case. The efficiency in this case relative to the logarithm will also be determined by the speed at which int -> float conversion can occur.
Edit:
I just realised the question was about double. The modified result is:
int16_t getLength(double a){
uint64_t bits;
std::memcpy(&bits, &a, sizeof(uint64_t));
int16_t exp = (f >> 52) & 0b11111111111; // There is no 11 bit long int so this has to do
exp -= 1023;
exp /= 3.32;
return exp + 1;
}
There are some changes so that it behaves better (and also less shifting).
You can also use frexp() to get the exponent without bias.
If the number is whole, keep dividing by 10, until you're at 0. You'd have to divide 100000 6 times, for example. For the fractional part, you need to keep multiplying by 10 until trunc(f) == f.
Recently i write a block of code:
const int sections = 10;
for(int t= 0; t < 5; t++){
int i = pow(sections, 5- t -1);
cout << i << endl;
}
And the result is wrong:
9999
1000
99
10
1
If i using just this code:
for(int t = 0; t < 5; t++){
cout << pow(sections,5-t-1) << endl;
}
The problem doesn't occur anymore:
10000
1000
100
10
1
Does anyone give me an explaination? thanks you very much!
Due to the representation of floating point values pow(10.0, 5) could be 9999.9999999 or something like this. When you assign that to an integer that got truncated.
EDIT: In case of cout << pow(10.0, 5); it looks like the output is rounded, but I don't have any supporting document right now confirming that.
EDIT 2: The comment made by BoBTFish and this question confirms that when pow(10.0, 5) is used directly in cout that is getting rounded.
When used with fractional exponents, pow(x,y) is commonly evaluated as exp(log(x)*y); such a formula would mathematically correct if evaluated with infinite precision, but may in practice result in rounding errors. As others have noted, a value of 9999.999999999 when cast to an integer will yield 9999. Some languages and libraries use such a formulation all the time when using an exponentiation operator with a floating-point exponent; others try to identify when the exponent is an integer and use iterated multiplication when appropriate. Looking up documentation for the pow function, it appears that it's supposed to work when x is negative and y has no fractional part (when x is negative and `y is even, the result should be pow(-x,y); when y is odd, the result should be -pow(-x,y). It would seem logical that when y has no fractional part a library which is going to go through the trouble of dealing with a negative x value should use iterated multiplication, but I don't know of any spec dictating that it must.
In any case, if you are trying to raise an integer to a power, it is almost certainly best to use integer maths for the computation or, if the integer to be raised is a constant or will always be small, simply use a lookup table (raising numbers from 0 to 15 by any power that would fit in a 64-bit integer would require only a 4,096-item table).
From Here
Looking at the pow() function: double pow (double base, double exponent); we know the parameters and return value are all double type. But the variable num, i and res are all int type in code above, when tranforming int to double or double to int, it may cause precision loss. For example (maybe not rigorous), the floating point unit (FPU) calculate pow(10, 4)=9999.99999999, then int(9999.9999999)=9999 by type transform in C++.
How to solve it?
Solution1
Change the code:
const int num = 10;
for(int i = 0; i < 5; ++i){
double res = pow(num, i);
cout << res << endl;
}
Solution2
Replace floating point unit (FPU) having higher calculation precision in double type. For example, we use SSE in Windows CPU. In Code::Block 13.12, we can do this steps to reach the goal: Setting -> Compiler setting -> GNU GCC Compile -> Other options, add
-mfpmath=sse -msse3
The picture is as follows:
(source: qiniudn.com)
Whats happens is the pow function returns a double so
when you do this
int i = pow(sections, 5- t -1);
the decimal .99999 cuts of and you get 9999.
while printing directly or comparing it with 10000 is not a problem because it is runded of in a sense.
If the code in your first example is the exact code you're running, then you have a buggy library. Regardless of whether you're picking up std::pow or C's pow which takes doubles, even if the double version is chosen, 10 is exactly representable as a double. As such the exponentiation is exactly representable as a double. No rounding or truncation or anything like that should occur.
With g++ 4.5 I couldn't reproduce your (strange) behavior even using -ffast-math and -O3.
Now what I suspect is happening is that sections is not being assigned the literal 10 directly but instead is being read or computed internally such that its value is something like 9.9999999999999, which when raised to the fourth power generates a number like 9999.9999999. This is then truncated to the integer 9999 which is displayed.
Depending on your needs you may want to round either the source number or the final number prior to assignment into an int. For example: int i = pow(sections, 5- t -1) + 0.5; // Add 0.5 and truncate to round to nearest.
There must be some broken pow function in the global namespace. Then std::pow is "automatically" used instead in your second example because of ADL.
Either that or t is actually a floating-point quantity in your first example, and you're running into rounding errors.
You're assigning the result to an int. That coerces it, truncating the number.
This should work fine:
for(int t= 0; t < 5; t++){
double i = pow(sections, 5- t -1);
cout << i << endl;
}
What happens is that your answer is actually 99.9999 and not exactly 100. This is because pow is double. So, you can fix this by using i = ceil(pow()).
Your code should be:
const int sections = 10;
for(int t= 0; t < 5; t++){
int i = ceil(pow(sections, 5- t -1));
cout << i << endl;
}
I'm having an issue creating a function that checks if a root can be simplified. In this example, I'm trying to simplify the cube root of 108, and the first number that this should work for is 27.
In order to do this, I am calling pow() with the number being the index (in this case, 27), and the power being (1/power), which in this instance is 3. I then compare that to the rounded answer of pow(index,(1/power)), which should also be 3.
Included is a picture of my problem, but basically, I am getting two answers that are equivalent to 3, yet my program is not recognizing them as equal. It seems to be working elsewhere in my program, but will not work here. Any suggestions as to why?
int inside = insideVal;
int currentIndex = index;
int coeff = co;
double insideDbl = pow(index, (1/(double)power));
double indexDbl = round(pow(index,(1/(double)power)));
cout<<insideDbl<< " " << indexDbl <<endl;
//double newPow = (1/(double)power);
vector<int> storedInts = storeNum;
if(insideDbl == indexDbl){
if(inside % currentIndex == 0){
storedInts.push_back(currentIndex);
return rootNumerator(inside/currentIndex, currentIndex, coeff, power, storedInts);
}
else{
return rootNumerator(inside, currentIndex + 1, coeff, power, storedInts);
}
}
else if(currentIndex < inside){
return rootNumerator(inside, currentIndex + 1, coeff, power, storedInts);
}
I tried to add a picture, but my reputation apparently wasn't high enough. In my console, I am getting "3 3" for the line that reads cout<<insideDbl<< " " << indexDbl <<endl;
EDIT:
Alright, so if the answers aren't exact, why does the same type of code work elsewhere in my program? Taking the 4th Root of 16 (which should equal 2) works using this segment of code:
else if( pow(initialNumber, (1/initialPower)) == round(pow(initialNumber,(1/initialPower)))){
int simplifiedNum = pow(initialNumber, (1/initialPower));
cout<<simplifiedNum;
Value* simplifiedVal = new RationalNumber(simplifiedNum);
return simplifiedVal;
}
despite the fact that the conditions are exactly the same as the ones that I'm having trouble with.
Well you are a victim of finite precision floating point arithmetic.
What happened?
This if(insideDbl == indexDbl), is very dangerous and misleading. It is in fact a question whether (Note: I made up the exact numbers but I can give you precise ones) 3.00000000000001255 is the same as 2.999999999999996234. I put 14 0s and 14 9s. So technically the difference goes beyond 15 most significant places. This is important.
Now if you write insideDbl == indexDbl, the compiler compares the binary representantions of them. Which are clearly different. However, when you simply print them, the default precision is like 5 or 6 significant digits, so they get rounded, and seem to be the same.
How to check it?
Try printing them with:
typedef std::numeric_limits< double > dbl_limits;
cout.precision(dbl::max_digits10);
cout << "Does " << insideDbl << " == " << indexDbl << "?\n";
This will set the precision, to the number of digits, the are necessary to differentiate two numbers. Please note that this is higher than the guaranteed precision of computation! That is the root of confusion.
I would also encourage reading numeric_limits. Especially about digits10, and max_digits10.
Why sometimes it works?
Because sometimes two algorithms will end up using the same binary representation for the final results, and sometimes they won't.
Also 2 can be a special case, as I believe it can be actually represented exactly in binary form. I think (but won't put my head on it.) all powers of 2 (and their sums) can be, like 0,675 = 0,5+0,125 = 2^-1 + 2^-3. But please don't take it for granted unless someone else confirms it.
What can you do?
Stick to the precise computations. Using integers, or whatever. Or you could assume that everything 3.0 +/- 10^-10 is actually 3.0 (epsilon comparisons), which is very risky, to say the least, when you do care about precise math.
Tl;dr: You can never compare two floats or doubles for equality, even when mathematically you can prove the mentioned equality, because of the finite precision of computations. That is, unless you are actually interested in the same binary representation of the value, as opposed to the value itself. Sometimes this is the case.
I suspect that you'll do better by computing the prime factorisation of insideVal and taking the product of those primes that appear in a multiple of the root.
For example
108 = 22 × 33
and hence
3√108 = 3 × 3√22
and
324 = 22 × 34
and hence
3√324 = 3 × 3√(22 × 3)
You can use trial division to construct the factorisation.
Edit A C++ implementation
First we need an integer overload for pow
unsigned long
pow(unsigned long x, unsigned long n)
{
unsigned long p = 1;
while(n!=0)
{
if(n%2!=0) p *= x;
n /= 2;
x *= x;
}
return p;
}
Note that this is simply the peasant algorithm applied to powers.
Next we need to compute the prime numbers in sequence
unsigned long
next_prime(const std::vector<unsigned long> &primes)
{
if(primes.empty()) return 2;
unsigned long p = primes.back();
unsigned long i;
do
{
++p;
i = 0;
while(i!=primes.size() && primes[i]*primes[i]<=p && p%primes[i]!=0) ++i;
}
while(i!=primes.size() && primes[i]*primes[i]<=p);
return p;
}
Note that primes is expected to contain all of the prime numbers less than the one we're trying to find and that we can quit checking once we reach a prime greater than the square root of the candidate p since that could not possibly be a factor.
Using these functions, we can calculate the factor that we can take outside the root with
unsigned long
factor(unsigned long x, unsigned long n)
{
unsigned long f = 1;
std::vector<unsigned long> primes;
unsigned long p = next_prime(primes);
while(pow(p, n)<=x)
{
unsigned long i = 0;
while(x%p==0)
{
++i;
x /= p;
}
f *= pow(p, (i/n));
primes.push_back(p);
p = next_prime(primes);
}
return f;
}
Applying this to your example
std::cout << factor(108, 3) << std::endl; //output: 3
gives the expected result. For another example, try
std::cout << factor(3333960000UL, 4) << std::endl; //output: 30
which you can confirm is correct by noting that
3333960000 = 304 × 4116
and checking that 4116 doesn't have any factor that is a power of 4.
I want to write the program that Calculate 2^x mod n = 1 we have n is an integer but, we should calculate x.I wrote the code but my code work too slow in big n.Can you suggest me a good way that work less than 1 second to solve this problem.
here is my code:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long int n,cntr=1,cheak;
cin >> n;
while (1)
{
if (n % 2 == 0)
{
break;
}
cheak=pow(2, cntr);
if (cheak % n == 1)
break;
cntr++;
}
cout << cntr << endl;
}
Some suggested modifications to your current approach: Note: a better approach follows!
Change your long long int to unsigned long long int. This will give you one more bit.
Change while (1) to while (cntr < 64). The size of unsigned long long is likely only 64 bits. (It's guaranteed to be at least 64 bits, but not larger than that.) You would then need to check whether your loop succeeded, however.
Change cheak to calculate 2n as 1ull << cntr. Make sure to include the ull suffix, which says this is an unsigned long long.
The << operator shifts bits to the left. Shifting all the bits to the left by 1 doubles the integer value of the number, assuming no bits "shifted away" off the left of the value. So, 1 << n will compute 2n.
The suffix ull indicates an integer constant is an unsigned long long. If you omit this suffix, 1 will be treated as an integer, and shift values above 31 will not do what you want.
However, all of the above are merely refinements on your current approach. It's worth understanding those refinements to better understand the language. They don't, however, look at the bigger picture.
Modular multiplication allows you to find (A * B) mod C as ( (A mod C) * (B mod C) ) mod C. How does that help us here?
We can rewrite the entire algorithm in a way that only limits N and X to the precision of the machine integers, and not 2N:
int main()
{
unsigned int modulus;
unsigned int raised = 2;
int power = 1;
std::cin >> modulus;
if (modulus % 2 == 1)
{
while (raised % modulus != 1)
{
raised = ((unsigned long long)raised * 2) % modulus;
power++;
}
std::cout << power << std::endl;
} else
{
std::cout << "modulus must be odd" << std::endl;
}
}
The cast to unsigned long long above allows modulus to be as large as 232 - 1, assuming unsigned int is 32 bits, without the computation overflowing.
With this approach, I was able to very quickly find answers even for very large inputs. For example, 111111111 returns 667332. I verified 2677332 mod 111111111 == 1 using the arbitrary precision calculator bc.
It's very fast. It computed 22323860 mod 4294967293 == 1 in less than 0.07 seconds on my computer.
Epilog: This highlights an important principle in programming: Really, this was a math problem more than a programming problem. Finding an efficient solution required knowing more about the problem domain than it did knowing about C++. The actual C++ code was trivial once we identified the correct mathematical approach.
It often goes this way, whether it's the mathematics or some other algorithmic aspect. And, it shouldn't surprise you to learn that discrete mathematics is where many of our graph and set algorithms come from. The programming language itself is a small piece of the big picture.
For each k between 1 and ceil(sqrt(n)), compute 2^k mod n and 2^(k ceil(sqrt(n))) mod n. Then compute the modular inverse of each 2^k. Sort all of the inverse(2^k)s into an array foo and the 2^(k ceil(sqrt(n))s into an array bar. There will be at least one value in common between the two arrays; find it. Say inverse(2^a) = 2^(b ceil(sqrt(n))). Then 2^(a + b ceil(sqrt(n))) = 1 (mod n).
How's your professor's sense of humor?
#include <iostream>
int main() { std::cout << 0 << '\n'; }
always prints a correct answer to the problem as stated.
pow is quite expensive in calculations, but if you have 2 as its first argument, you can better do a shift left, as shift left is equal to multiplying by 2:
cheak = (1 << cntr);
Recently i write a block of code:
const int sections = 10;
for(int t= 0; t < 5; t++){
int i = pow(sections, 5- t -1);
cout << i << endl;
}
And the result is wrong:
9999
1000
99
10
1
If i using just this code:
for(int t = 0; t < 5; t++){
cout << pow(sections,5-t-1) << endl;
}
The problem doesn't occur anymore:
10000
1000
100
10
1
Does anyone give me an explaination? thanks you very much!
Due to the representation of floating point values pow(10.0, 5) could be 9999.9999999 or something like this. When you assign that to an integer that got truncated.
EDIT: In case of cout << pow(10.0, 5); it looks like the output is rounded, but I don't have any supporting document right now confirming that.
EDIT 2: The comment made by BoBTFish and this question confirms that when pow(10.0, 5) is used directly in cout that is getting rounded.
When used with fractional exponents, pow(x,y) is commonly evaluated as exp(log(x)*y); such a formula would mathematically correct if evaluated with infinite precision, but may in practice result in rounding errors. As others have noted, a value of 9999.999999999 when cast to an integer will yield 9999. Some languages and libraries use such a formulation all the time when using an exponentiation operator with a floating-point exponent; others try to identify when the exponent is an integer and use iterated multiplication when appropriate. Looking up documentation for the pow function, it appears that it's supposed to work when x is negative and y has no fractional part (when x is negative and `y is even, the result should be pow(-x,y); when y is odd, the result should be -pow(-x,y). It would seem logical that when y has no fractional part a library which is going to go through the trouble of dealing with a negative x value should use iterated multiplication, but I don't know of any spec dictating that it must.
In any case, if you are trying to raise an integer to a power, it is almost certainly best to use integer maths for the computation or, if the integer to be raised is a constant or will always be small, simply use a lookup table (raising numbers from 0 to 15 by any power that would fit in a 64-bit integer would require only a 4,096-item table).
From Here
Looking at the pow() function: double pow (double base, double exponent); we know the parameters and return value are all double type. But the variable num, i and res are all int type in code above, when tranforming int to double or double to int, it may cause precision loss. For example (maybe not rigorous), the floating point unit (FPU) calculate pow(10, 4)=9999.99999999, then int(9999.9999999)=9999 by type transform in C++.
How to solve it?
Solution1
Change the code:
const int num = 10;
for(int i = 0; i < 5; ++i){
double res = pow(num, i);
cout << res << endl;
}
Solution2
Replace floating point unit (FPU) having higher calculation precision in double type. For example, we use SSE in Windows CPU. In Code::Block 13.12, we can do this steps to reach the goal: Setting -> Compiler setting -> GNU GCC Compile -> Other options, add
-mfpmath=sse -msse3
The picture is as follows:
(source: qiniudn.com)
Whats happens is the pow function returns a double so
when you do this
int i = pow(sections, 5- t -1);
the decimal .99999 cuts of and you get 9999.
while printing directly or comparing it with 10000 is not a problem because it is runded of in a sense.
If the code in your first example is the exact code you're running, then you have a buggy library. Regardless of whether you're picking up std::pow or C's pow which takes doubles, even if the double version is chosen, 10 is exactly representable as a double. As such the exponentiation is exactly representable as a double. No rounding or truncation or anything like that should occur.
With g++ 4.5 I couldn't reproduce your (strange) behavior even using -ffast-math and -O3.
Now what I suspect is happening is that sections is not being assigned the literal 10 directly but instead is being read or computed internally such that its value is something like 9.9999999999999, which when raised to the fourth power generates a number like 9999.9999999. This is then truncated to the integer 9999 which is displayed.
Depending on your needs you may want to round either the source number or the final number prior to assignment into an int. For example: int i = pow(sections, 5- t -1) + 0.5; // Add 0.5 and truncate to round to nearest.
There must be some broken pow function in the global namespace. Then std::pow is "automatically" used instead in your second example because of ADL.
Either that or t is actually a floating-point quantity in your first example, and you're running into rounding errors.
You're assigning the result to an int. That coerces it, truncating the number.
This should work fine:
for(int t= 0; t < 5; t++){
double i = pow(sections, 5- t -1);
cout << i << endl;
}
What happens is that your answer is actually 99.9999 and not exactly 100. This is because pow is double. So, you can fix this by using i = ceil(pow()).
Your code should be:
const int sections = 10;
for(int t= 0; t < 5; t++){
int i = ceil(pow(sections, 5- t -1));
cout << i << endl;
}