问题描述
如果我没记错的话,Machine Epsilon 的定义是满足条件的最低数字:
我试图使用 std::numeric_limits<float>::epsilon()
来测试这个,但如果您尝试使用 std::nextafter
获取先前的浮点数,则该值不满足这一点:
#include <cmath>
#include <iostream>
#include <limits>
int main() {
float e = std::numeric_limits<float>::epsilon();
float prevIoUs = std::nextafter(e,-std::numeric_limits<float>::infinity());
std::cout << std::boolalpha << ((1.0f + prevIoUs) > 1.0f) << std::endl;
return 0;
}
这仍然输出 true
https://coliru.stacked-crooked.com/a/841e19dafcf0bf6f。
在尝试使用 std::nextafter
获取数字后,我注意到正确的 Machine Epsilon 应该是:
std::nextafter(std::numeric_limits<float>::epsilon() / 2.0f,std::numeric_limits<float>::infinity())
我使用此代码对其进行了测试:
#include <cmath>
#include <iostream>
#include <limits>
bool verify(float e) {
return ((1.0f + e) > 1.0f);
}
int main() {
std::cout.precision(std::numeric_limits<float>::digits);
std::cout << std::boolalpha << std::fixed;
float epsilon = std::numeric_limits<float>::epsilon();
float last = epsilon;
while (true) {
last = std::nextafter(last,-std::numeric_limits<float>::infinity());
if ((1.0f + last) > 1.0f) {
epsilon = last;
} else {
break;
}
}
// Does not satisfy condition
std::cout << "last: " << verify(last) << " " << last << std::endl;
// Satisfy condition
std::cout << "epsilon: " << verify(epsilon) << " " << epsilon << std::endl;
float half_epsilon = std::numeric_limits<float>::epsilon() / 2.0f;
float actual_epsilon = std::nextafter(half_epsilon,std::numeric_limits<float>::infinity());
// Same as 'last' at this point
std::cout << "half_epsilon: " << verify(half_epsilon) << " " << half_epsilon << std::endl;
// Same as 'epsilon' at this point
std::cout << "actual_epsilon: " << verify(actual_epsilon) << " " << actual_epsilon << std::endl;
return 0;
}
这个输出
last: false 0.000000059604644775390625
epsilon: true 0.000000059604651880817983
half_epsilon: false 0.000000059604644775390625
actual_epsilon: true 0.000000059604651880817983
https://coliru.stacked-crooked.com/a/3c66a2144e80a91b
我在这里遗漏了什么吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)