Just a random thought:
0^0 is undefined, so a good exponential function should throw an exception if this is encountered, not return 1.
And I cannot understand why exp3 is slower in Nick's test. It is not slower on my computer/compiler.
Printable View
Just a random thought:
0^0 is undefined, so a good exponential function should throw an exception if this is encountered, not return 1.
And I cannot understand why exp3 is slower in Nick's test. It is not slower on my computer/compiler.
It's the user's fault. Besides some people define 0^0 to
be 1.
go back to school, take some math; he who defines 0^0 to equal 1 is wrong.Quote:
Originally posted by Nick
It's the user's fault. Besides some people define 0^0 to
be 1.
Argument that 0^0 should be defined as 1:
lim{x->0} (x^x) = 1
This argument is not valid, because:
lim{x->0} (x^(1/ln x)) = e
this implies that we should define 0^0 as e
Conclusion: It is hard to find a meaningful definition of 0^0
Only in dire circumstances.
http://www.sosmath.com/calculus/powser/powser01.html
Look at the summation definition.
When n = 0 and x = x_0 the series is undefined.
They should give notice to that fact.
I think exp3 is slower because the compiler generates
extra code for the bitwise and instead of just using
the test instruction.
Well, I certainly can't see a reason for throwing an exception. Why add that bulk to your code when it was the user's fault?? Better to break right where the problem occurs than slowing things down "just in case". But I know you are just being thoughtful...
...0^0 == 1? Sounds illogical! Anyway, these make unexceptable preconditions so again, let it return 0 and be assured the problem get's fixed. ;)
Good work Nick, too. That last algorithm was quite impressive.
nope you should throw an exception. Same as Division by zero. Let the caller of the code catch the exception and deal with it. Clean,easy to maintain and self documenting code that behaves correctly and predictably should be your goal.Exceptions can give you that if they are used correctly.
No, the exception can be thrown by the caller. Once he/she has perfected the algorithm, the exception handler can be removed to improve speed. Think about it. If you had a dollar for every exception you through for the sake of flawed preconditions...
Defensive programming has it's place. But don't overdo it.
The caller of this function catches logic_error and knows something awry has happened.Code:template <typename number>
number exponential( number n, int order ) {
if( order == 0 ) {
throw std::logic_error; // or better your class derived from std::logic_error
}
number value = n;
while(--order) {
value *= n;
}
return value;
}
The caller of this function gets back 0 and has no idea what happened.Code:template <typename number>
number exponential( number n, int order ) {
if( order == 0 ) {
return 0;
}
number value = n;
while(--order) {
value *= n;
}
return value;
}
Use exceptions in c++. Use return values to signify error in c.
I think your better off just defining the function
so that exp(0, 0) = 1. java, math.h and maybe a few more
languages all define it to be 1.
What? My <cmath> header returns nan (not-a-number) for pow(0,0)Quote:
Originally posted by Nick
I think your better off just defining the function
so that exp(0, 0) = 1. java, math.h and maybe a few more
languages all define it to be 1.
Probably carelessness, but make that:Quote:
Originally posted by Stoned_Coder
if( order == 0 ) {
throw std::logic_error; // or better your class derived from
std::logic_error
}
if (order == 0 && n == 0)
3^0 is not undefined.