簡體   English   中英

<Functional> :加 <long> 整數上的()給出了意想不到的結果

[英]<Functional>: plus<long>() on integers gives unexpected result

我不明白為什么在這兩種情況下我得不到相同的結果:

#include <iostream>
#include <vector>
#include <numeric> // for accumulate
#include <functional> // for plus()
using namespace std;

int main() {
    long long i = (long long)  0xFFFFFFFF + 2;
    cout << i << endl;

    vector<int> v;
    v.push_back(0xFFFFFFFF);
    v.push_back(2);

    long long r = accumulate(v.begin(), v.end(), 0, plus<long long>());
    cout << r << endl;

    return 0;
}

任何想法?

編輯:正如下面正確指出的那,這是由於我沒有指望的int中的符號位。 0x7FFFFFFF顯然會更好地進行測試。 另外,我錯誤地期望plus()的返回類型與accumulate()的返回類型相同,但情況並非如此:它基於第三個參數。

這里有兩個問題:

  1. 數字0xFFFFFFFF將不適合int (假設為32位int ),因此在大多數實現中,存儲在向量中的值實際上為-1。 使用vector<unsigned int>vector<long long>應該解決這個問題。

  2. accumulate返回的類型是從第三個參數推導出的類型。 由於你傳入0 ,這將是int 你應該傳入0LL以便它返回long long

具有這兩個修復程序的此程序將返回正確的結果:

#include <iostream>
#include <vector>
#include <numeric> // for accumulate
#include <functional> // for plus()
using namespace std;

int main() {
    long long i = (long long)  0xFFFFFFFF + 2;
    cout << i << endl;

    vector<long long> v; //or vector<unsigned int>
    v.push_back(0xFFFFFFFF);
    v.push_back(2);

    long long r = accumulate(v.begin(), v.end(), 0LL, plus<long long>());
    cout << r << endl;

    return 0;
}

因為你的vector包含int類型而0xFFFFFFFF不適合它。 嘗試將其更改為long long

#include <iostream>
#include <vector>
#include <numeric> // for accumulate
#include <functional> // for plus()
using namespace std;

int main() {
    long long i = (long long)  0xFFFFFFFF + 2;
    cout << i << endl;

    vector<long long> v;
    v.push_back(0xFFFFFFFF);
    v.push_back(2);

    long long r = accumulate(v.begin(), v.end(), 0LL, plus<long long>());
    cout << r << endl;

    return 0;
}

編輯:

另外,正如interjay所指出的,第三個參數應該具有long long類型long long因為accumulate使用它來推導出結果類型。

你的vector存儲類型int ,它可能是32位類型。 從4.7 / 3我們學到:

如果目標類型已簽名,則如果可以在目標類型(和位字段寬度)中表示該值,則該值不會更改; 否則,該值是實現定義的。

換句話說,您的值0xFFFFFFFF無法在目標簽名類型中表示,因此結果是實現定義的。 在這種情況下,它很可能采用了明顯的二進制結果並在向量中存儲了-1 然后當你進行accumulate ,它會加-1 (因為它不會改變存儲的-1)和2 ,導致打印1

很可能你想在向量中存儲long long (因為你總結的值大於32位可以容納),並且如其他答案中所述,你還需要傳遞0LL來累積以強制它推斷出正確的回報類型。

暫無
暫無

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

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