我可以写 const expression double 是两个 ulp 小于 -0.5
Can I write const expression double that is two ulps less than -0.5
我有一组基于通过 json 数据包接收到的数字的浮点计算。在计算结束时,我要求其中一个数字 >= -0.5。我发现有时我有一个未通过测试的值,因为它比阈值低 ULP。反正有没有写一个constexpression,意思是
constexpr auto threshold = -0.5 - 2*ULP;
或者我必须求助于
auto threshold = -0.5;
threshold = std::nexttoward(threshold, -2.0);
threshold = std::nexttoward(threshold, -2.0);
您应该能够通过 epsilon
达到所需的阈值,例如
constexpr auto threshold = -0.5 - std::numeric_limits<double>::epsilon();
如果您认为确实需要,可以添加 *2
,但由于 epsilon
是为值 1.0
定义的,因此它可能正好适合您 [=16] =].
或者,不要将其用作 constexpr
。除非它是一些对性能非常敏感的代码中的一些内部循环,否则差异应该可以忽略不计:
const auto threshold = std::nexttoward(std::nexttoward( -0.5, -2.0), -2.0);
也许像这样的东西可以做到(它需要以 2 为基数的浮点表示,并且不适用于非正规化):
constexpr double num = -0.5;
constexpr double threshold = num +
2.0
* (num < 0 ? -1 : 1)
* std::pow(2.0,
std::floor(std::log(std::abs(num)) / std::log(2.0)))
* std::numeric_limits<double>::epsilon();
它是如何工作的(我描述它时考虑的是 IEEE754)?
当数字在 [1.0;2.0) 范围内时,Epsilon 表示 1 ULP。我们需要缩放 epsilon,所以它总是意味着 1 ULP。比例基于浮点数的指数部分。如果数字是[1.0;2.0),那么比例必须是1。如果数字是[2.0;4.0),那么比例必须是2,对于[4.0;8.0),它必须是4,等等。所以,我们需要找到最近的、小于或等于 2 的幂:它是 2^floor(log2(number))
。我们需要处理负数,这就是公式中 abs
和 (num<0?-1:1)
的原因。
我有一组基于通过 json 数据包接收到的数字的浮点计算。在计算结束时,我要求其中一个数字 >= -0.5。我发现有时我有一个未通过测试的值,因为它比阈值低 ULP。反正有没有写一个constexpression,意思是
constexpr auto threshold = -0.5 - 2*ULP;
或者我必须求助于
auto threshold = -0.5;
threshold = std::nexttoward(threshold, -2.0);
threshold = std::nexttoward(threshold, -2.0);
您应该能够通过 epsilon
达到所需的阈值,例如
constexpr auto threshold = -0.5 - std::numeric_limits<double>::epsilon();
如果您认为确实需要,可以添加 *2
,但由于 epsilon
是为值 1.0
定义的,因此它可能正好适合您 [=16] =].
或者,不要将其用作 constexpr
。除非它是一些对性能非常敏感的代码中的一些内部循环,否则差异应该可以忽略不计:
const auto threshold = std::nexttoward(std::nexttoward( -0.5, -2.0), -2.0);
也许像这样的东西可以做到(它需要以 2 为基数的浮点表示,并且不适用于非正规化):
constexpr double num = -0.5;
constexpr double threshold = num +
2.0
* (num < 0 ? -1 : 1)
* std::pow(2.0,
std::floor(std::log(std::abs(num)) / std::log(2.0)))
* std::numeric_limits<double>::epsilon();
它是如何工作的(我描述它时考虑的是 IEEE754)?
当数字在 [1.0;2.0) 范围内时,Epsilon 表示 1 ULP。我们需要缩放 epsilon,所以它总是意味着 1 ULP。比例基于浮点数的指数部分。如果数字是[1.0;2.0),那么比例必须是1。如果数字是[2.0;4.0),那么比例必须是2,对于[4.0;8.0),它必须是4,等等。所以,我们需要找到最近的、小于或等于 2 的幂:它是 2^floor(log2(number))
。我们需要处理负数,这就是公式中 abs
和 (num<0?-1:1)
的原因。