簡體   English   中英

Collat​​z Conjecture c ++怪異輸出

[英]Collatz Conjecture c++ weird output with big numbers

所以,我很無聊,決定完全隨機地做一些事情,然后我碰到了collat​​z猜想:從任何正數開始,如果是正數,則除以2。 如果是奇數,則乘以三並加一。 重復此操作時,您將排名第一。 所以我做了這段代碼:

//盧卡斯·諾克(Collasz Conjecture)

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    long long n;
    cin >> n;
    cout << setw(5) << n;

    while(true){
        if(n % 2 == 0 && n != 1){
            //is even
            cout << " E" << endl;
            n /=2;
            cout << setw(5) << n;
        }
        else if(n != 1){
            //is odd
            cout << " O" << endl;
            n = n * 3 + 1;
            cout << setw(5) << n;
        }
        else break;
    }
    cout << " O" << endl << endl << "end loop";
    return 0;
}

我仍在學習c ++(我剛剛完成了sololearn課程,並且即將獲得“ C ++ for dummies all-one-one”一書),但是我認為這對我來說是一個很好的開始,並且有效。

只有一個小問題:如果我使用大數,它的確會停在一個數上,並得到奇數甚至偶數,但是...

輸入“ 1000000000000000000000000 ”時,請看輸出的第一部分:

9223372036854775807 O
9223372036854775806 E
4611686018427387903 O
-4611686018427387906 E
-2305843009213693953 O
-6917529027641081858 E
-3458764513820540929 O
8070450532247928830 E
4035225266123964415 O
-6341068275337658370 E
-3170534137668829185 O
8935141660703064062 E
4467570830351532031 O
-5044031582654955522 E
-2522015791327477761 O
-7566047373982433282 E
-3783023686991216641 O
7097673012735901694 E
3548836506367950847 O
-7800234554605699074 E

嗯,這有點奇怪,不是嗎? (不要看換行符,它是完美堆疊的,只是在這里不顯示,因為我復制了輸出)

有人可以解釋一下為什么會發生這種情況以及如何解決嗎?

您已經超出了long long整數值的限制。 輸出中的第一個值被截斷為比輸入小得多,然后到達4611686018427387903它乘以3,因為它不是偶數。 那是當它溢出類型並包裝成負值時。 您需要使用BigInteger庫,例如TTMath

基本上就像其他人指出的那樣,您不檢查溢出。 但我想指出的是另一回事,您的代碼仍然無效,因為您無需檢查是否陷入無限循環,當乘法和除法序列生成相同的數字時,您的時間將永遠不會結束。

這是帶有簡單溢出檢測的正確代碼:

#include <iostream>
#include <unordered_set>

bool colatazConjecture(int n) {
    std::unordered_set<int> localComputed;
    int newN = 0;

    while (n != 1) {
        if (!localComputed.emplace(n).second) {
            throw "Cycle detected";
        }

        newN = n;
        if (n & 0x1) {
            newN = 3*n + 1;
            if (newN <= n) {
                throw std::overflow_error("Overflow for " + std::to_string(newN));
            }
        } else {
            newN >>= 1;
        }
        n = newN;
    }
}

暫無
暫無

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

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