How to Set Returned Value of Log10(0)?
Code: #Include #Include Using Namespace Std; Int Main () { Double Result = Log10(0.0); Cout 0) { Cout
Code:
#include <iostream>
#include <math.h>
using namespace std;
int main ()
{
double result = log10(0.0);
cout << result;
}
When I execute log10(0) in C++, It prints to me -inf.
Is it fixed for every library/compiler I'll use?
Or could it change in different platforms?
How would you manage the pole error keeping double?
4 Answers
According to cplusplus, it depends on the library what you get for log10(0). However, in general the value of log10(0) is not defined (can be -inf if you like, but it is not a real number). Usually, you should prevent such undefined results (not undefined in the C++ sense of Undefined Behaviour, but in a mathematical sense) before they happen. E.g.
double x;
x = foo();
if ( x <= 0 ) {
/* handle this case extra */
else {
y = log10(x);
}
What value you use in the case of log10(0) depends very much on your application. However, I think it is easier to check for 0 before doing the calculation instead of relying on log10(0) returning some particular value (as it might be -inf or something completely different).
The behavior is very clear-cut for log10 for floating point implementations that are IEC 60559 compliant:
- If the argument is ±0, -∞ is returned and
FE_DIVBYZEROis raised.- If the argument is 1, +0 is returned
- If the argument is negative, NaN is returned and
FE_INVALIDis raised.- If the argument is +∞, +∞ is returned
- If the argument is NaN, NaN is returned
This list would allow you to conditionally handle each case for compliant implementations. But honestly, we know that only the range (+0, +∞) is supported, so whether your implementation is compliant or not you could simply guard your log10 with an if-block.
A great way to write this if-block is with isnormal if you don't want to allow denormals or isfinite if you do want to support denormals. For example, given a floating point variable foo:
if(isfinite(foo) && foo > 0) {
cout << log10(foo) << endl;
} else {
cout << "foo is invalid\n";
}
But the answer to your question is no -∞ will not always be returned. But C++ does guarantee a return: Given log10(foo):
- If
foois afloatthe return will always be-HUGE_VALF - If
foois adoublethe return will always be-HUGE_VAL - If
foois along doublethe return will always be-HUGE_VALL
On implementations that support floating-point infinities, these macros always expand to the positive infinities of
float,double, andlong double, respectively [source]
Whether your implementation supports infinity or whether these values expand to the maximum floating point value, the right way to handle this is still probably isnormal/isfinite but you could also test the return of log10:
const auto result = log10(foo);
if(is_same_v<decltype(foo), float> && result == -HUGE_VALF ||
is_same_v<decltype(foo), double> && result == -HUGE_VAL ||
is_same_v<decltype(foo), long double> && result = -HUGE_VALL) {
cout << "foo is invalid\n";
} else {
cout << result << endl;
}
Well c++ ref gives clear answer: cpp ref.
If the argument is ±0, -∞ is returned and FE_DIVBYZERO is raised.
So yes, log10(0) will give you -inf, doesn't matter what library/compiler you use (as long as it's in line with spec).
In math there is no option to calculate log(0)