[英]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: 笔记:
ceil
for the original expression may be conservative. ceil
可能是保守的。 For example, if pi(...)=12.2, there are 12 primes number at most, not 13.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.