簡體   English   中英

這個 unsigned long long 如何轉化為在這個 for 循環中評估 3-100 素數的點?

[英]How does this unsigned long long translate to being a point to evaluate prime numbers from 3-100 in this for loop?

int main()

{

puts('2');

for (unsigned long long b = 04224646226462667ull, p = 3; b; p += 2, b /= 2)

if (b % 2) printf("%lld\n", p);

return 0;

}

我在網上找到了一個帖子,其中有人試圖與一個要求家庭作業解決方案的孩子搞砸,而對於我的生活,我無法弄清楚。 我知道這可能與對 unsigned long long 執行的整數除法有關,但除此之外,我看不出是什么促進了它排除了 100 范圍內的某些值。

這是它的一個不太傾斜的版本:

int main()
{
#define bit(n)  (1ull<<(n))
    unsigned long long bitmask = 04224646226462667ull;
    puts("2");

    for (int i=0; bit(i) < bitmask; i++)
        if (bitmask & bit(i))
            printf("%u\n", 3 + i*2);

    return 0;
}

所以有趣的文字是 3 到 100 之間素數的壓縮編碼。壓縮消除了所有偶數(顯然不是素數),因此如果設置了位 i,那么相應的素數是 3 + i * 2。

基於以下事實,作者有效地將素數序列隱藏在一個常數中

  1. 2 到 100 之間的質數少於 63 個,因此可以使用使用 ULL 的 64 位的編碼。
  2. 從 3 開始,它只導航 3 到 99 之間的奇數。 由於在 3...99 中只有 49 個這樣的數字,我們有很多位要編碼。
  3. 每次迭代有效地將b右移一位( b /= 2 )。

因此,通過對常量進行編碼,如果值p是素數,則b的零位在當前迭代中點亮,並且您只在特定情況下打印p ,結果是一個數字列表,詳細說明編碼的內容,僅此而已。 在這種情況下,編碼是素數,但數字是素數與實際數學無關; 這完全是關於預先確定的編碼、位移以及如果第一個位在位移后點亮則報告計數器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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