Casting from (long)double to size_t

Casting from (long)double to size_t

本文关键字:to size double from long Casting      更新时间:2023-10-16

我正在尝试尽可能高效地实现eratosthenes的筛子。我想将我的素数的长度设置为上限 pi(n) < 1.25506n / ln n但是我不确定如何进行转换以安全地进行操作,也不知道哪种类型的组合是最好的。

我列表的最大长度将受到数组的最大大小的限制。

我的猜测是理想的组合取决于如何内部实现size_t和上限。

我想获得的结果很近 ceil( 1.25506n / ln n)没有较小的数字。

有任何建议如何做?

这是一种方法:

#include <cstddef>
#include <cfloat>
#include <cmath>
std::size_t piUpperBound(std::size_t n) {
    double x = n;
    double num = nextafter(x, DBL_MAX);
    x = log(x);
    double den = nextafter(x, -DBL_MAX);
    double result = num/den;
    result = nextafter(1.25506, DBL_MAX)*nextafter(result, DBL_MAX);
    result = nextafter(result, DBL_MAX);
    return ceil(result);
}

此代码假设log最多有1 ULP错误。

基本想法是使用nextafter,它为我们提供了下一个可能的浮点号。每次操作后,我致电nextafter,以某种方式修改数字,以使结果表达式保持上限。

如果我们假设该划分,乘法正确(对于IEEE-754),则可以创建更好的绑定,而不是nextafter,我们可以调整舍入模式(始终向上或圆形)。p>注意:

  • 使用ceil进行原始表达可能是保守的。例如,如果pi(...)= 12.2,最多有12个素数,而不是13。
  • 您可以在这里看到这个公式非常保守。因此,实际上,不需要整个浮点业务。即使代码略微估计一点,它仍然会受到较大边距的上限。
相关文章: