[英]Casting from (long)double to size_t
我正在嘗試盡可能高效地實現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
,我們可以調整舍入模式(始終向上或向下舍入)。
筆記:
ceil
可能是保守的。 例如,如果pi(...)= 12.2,則最多有12個素數,而不是13。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.