I was resolving some online mathematics tests, and thought it's too hard to find the solutions and put it in a program on devc++, I should have
153,370,371,407,
but there was missing a solution 407.
Here is the question: The number 153 has an interesting property. In other words, it is equal to the sum of the cubes of its digits:
13 + 53 + 33 = 153
370 is another number with the same property. There are two other three-digit natural numbers with three different digits, both smaller than 500, that have the same property. Find them.
And here is my program
#include<iostream.h>
#include<math.h>
using namespace std;
int main() {
int i,nr,a,b,c;
for(i=100;i<=500;i++) {
nr=i;
c=i%10;
b=i/10%10;
a=i/10/10;
if((pow(a,3)+pow(b,3)+pow(c,3))==nr) cout<<nr<<endl;
}
system("pause");
}
Perhaps pows return double leading to floating point inaccuracy.
Instead, try
if(a*a*a + b*b*b + c*c*c == nr)
cout ....
( [EDIT] Resolved since. Mostly guessing the question from the partial code, since the question is terribly formatted at this point, and is not editable either for some reason. )
Floating point calculations are not always exact, and comparing floating point values for equality is generally ill advised.
To the point, replace
if((pow(a,3)+pow(b,3)+pow(c,3))==nr)
with
if((a*a*a + b*b*b + c*c*c) == nr)
When I run that program I get those 4 answers.
pow is never supposed to be imprecise enough to have any rounding in this trivial test.
But there seems to be a tend in questions on SO that both pull c headers into C++ and use system("pause"); that a version of pow is being used that is seriously less accurate than it ought to be. So the earlier two answers (suggesting a way to not use pow) may be effectively correct. But only because something is wrong with you math library, not because a valid copy of pow gets that bad.
So you could find a better C++ environment or better math headers, or you could start some seriously defensive programming around the flaws in your copy of pow
But if that doesn't fix it, the next thing to suspect would be endl isn't working quite correctly before that pause. Maybe you are seeing some output buffering problem. Anyway, I'm pretty sure the code is fine (even its use of pow) and the problem is in the math or I/O library functions.
Related
So i was in a computing contest and i noticed a weird bug. pow(26,2) would always return 675, and sometimes 674? even though correct answer is 676. These sort of errors also occur with pow(26,3), pow(26,4) etc
After some debugging after the contest i believe the answer has to do with the fact int rounds down. Interestingly this kind of error has never occured to me before. The computer i had was running mingw on windows 8. GCC version was fairly new, like 2-3 months old i believe. But what i found was that if i turned the o1/o2/o3 optimization flag on these sort of error would miraculously disappear. pow(26,2) would always get 676 aka correct answer Can anyone explain why?
#include <cmath>
#include <iostream>
using namespace std;
int main() {
cout<<pow(26,2)<<endl;
cout<<int(pow(26,2))<<endl;
}
Results with doubles are weird.
double a=26;
double b=2;
cout<<int(pow(a,b))<<endl; #outputs 675
cout<<int(pow(26.0,2.0))<<endl; # outputs 676
cout<<int(pow(26*1.00,2*1.00))<<endl; # outputs 676
The function pow operates on two floating-point values, and can raise one to the other. This is done through approximating algorithm, as it is required to be able to handle values from the smallest to the largest.
As this is an approximating algorithm, it sometimes gets the value a little bit wrong. In most cases, this is OK. However, if you are interested in getting an exact result, don't use it.
I would strongly advice against using it for integers. And if the second operand is known (2, in this case) it is trivial to replace this with code that does this much faster and that return the correct value. For example:
template<typename T>
T square(T x)
{
return x * x;
}
To answer the actual question: Some compilers can replace calls to pow with other code, or eliminate it all together, when one or both arguments are known. This explains why you get different results.
So i was in a computing contest and i noticed a weird bug. pow(26,2) would always return 675, and sometimes 674? even though correct answer is 676. These sort of errors also occur with pow(26,3), pow(26,4) etc
After some debugging after the contest i believe the answer has to do with the fact int rounds down. Interestingly this kind of error has never occured to me before. The computer i had was running mingw on windows 8. GCC version was fairly new, like 2-3 months old i believe. But what i found was that if i turned the o1/o2/o3 optimization flag on these sort of error would miraculously disappear. pow(26,2) would always get 676 aka correct answer Can anyone explain why?
#include <cmath>
#include <iostream>
using namespace std;
int main() {
cout<<pow(26,2)<<endl;
cout<<int(pow(26,2))<<endl;
}
Results with doubles are weird.
double a=26;
double b=2;
cout<<int(pow(a,b))<<endl; #outputs 675
cout<<int(pow(26.0,2.0))<<endl; # outputs 676
cout<<int(pow(26*1.00,2*1.00))<<endl; # outputs 676
The function pow operates on two floating-point values, and can raise one to the other. This is done through approximating algorithm, as it is required to be able to handle values from the smallest to the largest.
As this is an approximating algorithm, it sometimes gets the value a little bit wrong. In most cases, this is OK. However, if you are interested in getting an exact result, don't use it.
I would strongly advice against using it for integers. And if the second operand is known (2, in this case) it is trivial to replace this with code that does this much faster and that return the correct value. For example:
template<typename T>
T square(T x)
{
return x * x;
}
To answer the actual question: Some compilers can replace calls to pow with other code, or eliminate it all together, when one or both arguments are known. This explains why you get different results.
I am working through a beginning C++ class and my book(Starting Out with C++ Early Objects 7th edition) has a very poor example of how to check the value of a floating point variable.
The book example in question(filename pr4-04.cpp):
// This program demonstrates how to safely test a floating-point number
// to see if it is, for all practical purposes, equal to some value.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double result = .666667 * 6.0;
// 2/3 of 6 should be 4 and, if you print result, 4 is displayed.
cout << "result = " << result << endl;
// However, internally result is NOT precisely equal to 4.
// So test to see if it is "close" to 4.
if (abs(result - 4.0 < .0001))
cout << "result DOES equal 4!" << endl;
else
cout << "result DOES NOT equal 4!" << endl;
return 0;
}
And I use g++ in Ubuntu to compile my code like this:
g++ pr4-04.cpp -o pr4-04 && ./pr4-04
And I get this error:
error: call of overloaded ‘abs(bool)’ is ambiguous
I am able to fix this by changing abs() to fabs(), but this is still super confusing! Why is the book giving us things which won't compile, or is this just me? Why does the cout of 'result' give 4 instead of 4.000002? Why does this value seem to change when it is used in the if{} statement?
I get that we can't just use == to check for equivalence, but why do I need to use the absolute value? I get the same answer whether or not I use it. So what is the point?
Not to mention, this seems like a very poor way to check for floating point equivalence. Is there a better way to do this? This topic seems awfully important.
I found this topic here on stackoverflow, but their solution:
fabs(f1 - f2) < precision-requirement
fabs(f1 - f2) < max(fabs(f1), fabs(f2)) * percentage-precision-requirement
Doesn't make much sense to me in the context of my 4 chapters worth of C++ experience. I would greatly appreciate some help. Our book has given me a whopping 6 sentences of text to explain all of this.
Edit: As suggested by some I tried to find an errata page, but after 30mins of searching the textbook, internet, and my course website I was only able to find this downloadable zip file, which required a login -_-
I also copied the code perfectly. That was not MY typo, I copied it directly from a CD with the code on it. It is also typed that way in the book.
if (abs(result - 4.0 < .0001))
The parenthesis are wrong, you probably mean: if (abs(result-4.0) < .0001).
As to why it did not compile, the standard determines in §26.8p8 that
In addition to the double versions of the math functions in , C++ adds float and long double overloaded versions of these functions, with the same semantics.
The expression (result-4.0 < .0001) yields a bool, and there is no overload of abs that takes a bool argument, but there are multiple versions of abs for which the argument is implicitly convertible from bool. The compiler does not find one of the conversion sequences better than the rest and bails out with the ambiguity error.
The problem is clearly the line
if (abs(result - 4.0 < .0001))
which should be written as
if (abs(result - 4.0) < .0001)
I would assume that this is a simple typo. Report the error to the author of the book!
BTW, the original code does compile on my system without any problem, giving the expected result! That is, even if the author tested the code he may not have noticed that it is problematic!
Also answering the question on why abs() is needed: some decimal numbers are rounded to a floating point value which is slightly smaller than the expected result while others are rounded to number which are slightly bigger. In which direction the values are round (if at all: some decimal numbers can be represented exactly using binary floating points) is somewhat hard to predict. Thus, the result may be slightly bigger or slightly smaller than the expectation and the difference, thus, positive or negative, respectively.
We have some code that looks like this:
inline int calc_something(double x) {
if (x > 0.0) {
// do something
return 1;
} else {
// do something else
return 0;
}
}
Unfortunately, when using the flag /fp:fast, we get calc_something(0)==1 so we are clearly taking the wrong code path. This only happens when we use the method at multiple points in our code with different parameters, so I think there is some fishy optimization going on here from the compiler (Microsoft Visual Studio 2008, SP1).
Also, the above problem goes away when we change the interface to
inline int calc_something(const double& x) {
But I have no idea why this fixes the strange behaviour. Can anyone explane this behaviour? If I cannot understand what's going on we will have to remove the /fp:fastswitch, but this would make our application quite a bit slower.
I'm not familiar enough with FPUs to comment with any certainty, but my guess would be that the compiler is letting an existing value that it thinks should be equal to x sit in on that comparison. Maybe you go y = x + 20.; y = y - 20; y is already on the FP stack, so rather than load x the compiler just compares against y. But due to rounding errors, y isn't quite 0.0 like it is supposed to be, and you get the odd results you see.
For a better explanation: Why is cos(x) != cos(y) even though x == y? from the C++FAQ lite. This is part of what I'm trying to get across, I just couldn't remember where exactly I had read it until just now.
Changing to a const reference fixes this because the compiler is worried about aliasing. It forces a load from x because it can't assume its value hasn't changed at some point after creating y, and since x is actually exactly 0.0 [which is representable in every floating point format I'm familiar with] the rounding errors vanish.
I'm pretty sure MS provides a pragma that allows you to set the FP flags on a per-function basis. Or you could move this routine to a separate file and give that file custom flags. Either way, it could prevent your whole program from suffering just to keep that one routine happy.
what are the results of calc_something(0L), or calc_something(0.0f) ? It could be linked to the size of the types before casting. An integer is 4 bytes, a double is 8.
Have you tried looking at the asembled code, to see how the aforementioned conversion is done ?
Googling for 'fp fast', I found this post [social.msdn.microsoft.com]
As I've said in other question, compilers suck at generating floating point code. The article Dennis links to explains the problems well. Here's another: An MSDN article.
If the performance of the code is important, you can easily1 out-perform the compiler by writing your own assembler code. If your algoritm is vectorisable then you can make use of SIMD too (with a slight loss of precision though).
Assuming you understand the way the FPU works.
inline int calc_something(double x) will (probably) use an 80 bits register. inline int calc_something(const double& x) would store the double in memory, where it takes 64 bits. That at least explains the difference between the two.
However, I find your test quite fishy to begin with. The results of calc_something are extremely sensitive to rounding of its input. Your FP algorithms should be robust to rounding. calc_something(1.0-(1.0/3.0)*3) should be the same as calc_something(0.0).
I think the behavior is correct.
You never compare a floating point number up to less than the holding type's precision.
Something that comes from zero may be equal, greater or less than another zero.
See http://floating-point-gui.de/
I understand this is a classic programming problem and therefore I want to be clear I'm not looking for code as a solution, but would appreciate a push in the right direction. I'm learning C++ and as part of the learning process I'm attempting some programming problems. I'm attempting to write a program which deals with numbers up to factorial of 1billion. Obviously these are going to be enormous numbers and way too big to be dealing with using normal arithmetic operations. Any indication as to what direction I should go in trying to solve this type of problem would be appreciated.
I'd rather try to solve this without using additional libraries if possible
Thanks
PS - the problem is here http://www.codechef.com/problems/FCTRL
Here's the method I used to solve the problem, this was achieved by reading the comments below:
Solution -- The number 5 is a prime factor of any number ending in zero. Therefore, dividing the factorial number by 5, recursively, and adding the quotients, you get the number of trailing zeros in the factorial result
E.G. - Number of trailing zeros in 126! = 31
126/5 = 25 remainder 1
25/5 = 5 remainder 0
5/5 = 1 remainder 0
25 + 5 + 1 = 31
This works for any value, just keep dividing until the quotient is less
than 5
Skimmed this question, not sure if I really got it right but here's a deductive guess:
First question - how do you get a zero on the end of the number? By multiplying by 10.
How do you multiply by 10? either by multiplying by either a 10 or by 2 x 5...
So, for X! how many 10s and 2x5s do you have...?
(luckily 2 & 5 are prime numbers)
edit: Here's another hint - I don't think you need to do any multiplication. Let me know if you need another hint.
Hint: you may not need to calculate N! in order to find the number of zeros at the end of N!
To solve this question, as Chris Johnson said you have to look at number of 0's.
The factors of 10 will be 1,2,5,10 itself. So, you can go through each of the numbers of N! and write them in terms of 2^x * 5^y * 10^z. Discard other factors of the numbers.
Now the answer will be greaterof(x,y)+z.
One interesting thing I learn from this question is, its always better to store factorial of a number in terms of prime factors for easy comparisons.
To actually x^y, there is an easy method used in RSA algorithm, which don't remember. I will try to update the post if I find one.
This isn't a good answer to your question as you've modified it a bit from what I originally read. But I will leave it here anyway to demonstrate the impracticality of actually trying to do the calculations by main brute force.
One billion factorial is going to be out of reach of any bignum library. Such numbers will require more space to represent than almost anybody has in RAM. You are going to have to start paging the numbers in from storage as you work on them. There are ways to do this. The guy who recently calculated π out to 2700 billion places used such a library
Do not use the naive method. If you need to calculate the factorial, use a fast algorithm: http://www.luschny.de/math/factorial/FastFactorialFunctions.htm
I think that you should come up with a way to solve the problem in pseudo code before you begin to think about C++ or any other language for that matter. The nature of the question as some have pointed out is more of an algorithm problem than a C++ problem. Those who suggest searching for some obscure library are pointing you in the direction of a slippery slope, because learning to program is learning how to think, right? Find a good algorithm analysis text and it will serve you well. In our department we teach from the CLRS text.
You need a "big number" package - either one you use or one you write yourself.
I'd recommend doing some research into "large number algorithms". You'll want to implement the C++ equivalent of Java's BigDecimal.
Another way to look at it is using the gamma function. You don't need to multiply all those values to get the right answer.
To start you off, you should store the number in some sort of array like a std::vector (a digit for each position in the array) and you need to find a certain algorithm that will calculate a factorial (maybe in some sort of specialized class). ;)
//SIMPLE FUNCTION TO COMPUTE THE FACTORIAL OF A NUMBER
//THIS ONLY WORKS UPTO N = 65
//CAN YOU SUGGEST HOW WE CAN IMPROVE IT TO COMPUTE FACTORIAL OF 400 PLEASE?
#include <iostream>
#include <cmath>
using namespace std;
int factorial(int x); //function to compute factorial described below
int main()
{
int N; //= 150; //you can also get this as user input using cin.
cout<<"Enter intenger\n";
cin>>N;
factorial(N);
return 0;
}//end of main
int factorial(int x) //function to compute the factorial
{
int i, n;
long long unsigned results = 1;
for (i = 1; i<=x; i++)
{
results = results * i;
}
cout<<"Factorial of "<<x<<" is "<<results<<endl;
return results;
}