简体   繁体   English

从(long)double转换为size_t

[英]Casting from (long)double to size_t

I'm trying to implement Sieve of Eratosthenes as efficient as possible. 我正在尝试尽可能高效地实现Eratosthenes筛。 I'd like to set length of my prime array to upper bond of pi(n) < 1.25506n / ln n but I'm not sure how to proceed with conversions to do it safely, nor which combination of types is the best for this. 我想将素数数组的长度设置为pi(n) < 1.25506n / ln n上限,但是我不确定如何进行转换以安全地进行操作,也不知道哪种类型的组合最适合这个。

Maximal length of my list would be limited by maximal size of array. 我列表的最大长度将受到数组最大大小的限制。

My guess is that ideal combination depends of how size_t is implemented internally and it's upper limit. 我的猜测是,理想的组合取决于内部如何实现size_t及其上限。

I'd like to get result as close to ceil( 1.25506n / ln n) without ever getting smaller number. 我希望得到的结果接近ceil( 1.25506n / ln n)而不会越来越小。

Any advises on how to do that? 任何建议如何做到这一点?

Here's a way to do this: 这是一种方法:

#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);
}

This code supposes that log has at most 1 ulp error. 此代码假定log最多具有1个ulp错误。

The basic idea is to use nextafter , which provides us the next possible floating point number. 基本思想是使用nextafter ,它为我们提供了下一个可能的浮点数。 After each operation I call nextafter , to modify the number in a way so the resulting expression keeps being an upper bound. 每次操作后,我都调用nextafter ,以某种方式修改数字,使结果表达式始终保持上限。

A better bound could be created, if we suppose, that division, multiplication is correctly rounded (true for IEEE-754), and instead of nextafter , we could adjust rounding mode (to always round up or down). 如果我们想,可以创建一个更好的界限,即除法,乘法正确舍入(对于IEEE-754是正确的),并且代替nextafter ,我们可以调整舍入模式(始终向上或向下舍入)。

Notes: 笔记:

  • Using ceil for the original expression may be conservative. 对原始表达使用ceil可能是保守的。 For example, if pi(...)=12.2, there are 12 primes number at most, not 13. 例如,如果pi(...)= 12.2,则最多有12个素数,而不是13。
  • This formula is very conservative, as you can see here . 您可以在此处看到这个公式非常保守。 So, actually, this whole floating-point business is not required. 因此,实际上,不需要整个浮点业务。 Even if the code miscalculates a little bit, it will still be an upper bound by a large margin. 即使代码计算错误,它仍然是一个较大的上限。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM