问题
I'm just trying to compute a good sigmoid function in C++ (and efficient). So i have to do something like:1/(1 + exp(-x))
The problem is, when X
becomes big (or even small), the result of 1 + e
turns to be 0 or 1
For example,1 + exp(-30) = 1
But this is incorrect...
How can we add very small (or big) numbers easily and efficiently ?
Datatype I am using : double
Here is the code snippet:
double Quaternion::sigmoidReal(double v){
return 1.0 / ( 1.0 + exp(-v) ) ;
}
Thanks !
回答1:
I think you need to set the precision of cout
:
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::fixed;
std::cout << std::setprecision(30);
std::cout << (1 + exp(-30)) << std::endl;
getchar();
return 0;
}
Output:
1.000000000000093480778673438181
Note: Like people have noted in the comments, part of the output is noise (which at the time, I didn't consider). I was mostly just trying to demonstrate that you can put an arbitrary number into setprecision
.
This has to do with the maximum amount of information that can be saved in 1 double. Part of the bits is used for the exponent, and part for the actual digits. A more accurate way would be to print the number like this (without setting the precision):
std::cout << 1 << "+" << exp(-30) << std::endl;
Output:
1+9.35762e-14
Which still leaves the problem of saving a double with that actual value. However, it is possible, and wikipedia has a list of libraries that help with this: Link. The related article also has some more explanation.
来源:https://stackoverflow.com/questions/36547763/c-adding-1-to-very-small-number