簡體   English   中英

從(long)double轉換為size_t

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM