繁体   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