C ++中的大数问题

时间:2013-10-17 20:30:28

标签: c++ long-integer

我正在研究一个相对简单的问题,即基于将某个值下的所有素数加在一起。我写了一个应该完成这项任务的程序。我正在使用长类型变量。当我进入更高的数字(~200 / 300k)时,我用来跟踪总和的变量变为负数,尽管事实上没有添加任何负值(基于我的知识和我做过的一些测试) 。数据类型是否有问题,或者我遗漏了什么。

我的代码如下(在C ++中)[Vector基本上是一个动态数组,以防人们想知道]:

bool checkPrime(int number, vector<long> & primes, int numberOfPrimes) {
    for (int i=0; i<numberOfPrimes-1; i++) {
        if(number%primes[i]==0) return false;
    }
    return true;
}

long solveProblem10(int maxNumber) {
    long sumOfPrimes=0;
    vector<long> primes;
    primes.resize(1);
    int numberOfPrimes=0;
    for (int i=2; i<maxNumber; i++) {
        if(checkPrime(i, primes, numberOfPrimes)) {
            sumOfPrimes=sumOfPrimes+i;
            primes[numberOfPrimes]=long(i);
            numberOfPrimes++;
            primes.resize(numberOfPrimes+1);
        }
    }
    return sumOfPrimes;
}

5 个答案:

答案 0 :(得分:3)

整数表示值使用two's complement,这意味着最高位表示符号。当您将数字加到足够高时,会设置最高位(integer overflow)并且数字变为负数。

您可以使用unsigned long(32位,并且可能仍会溢出您正在求和的值)或使用unsigned long long(64位)来解决此问题。

答案 1 :(得分:2)

  

我用来跟踪总和的变量变为负数,尽管事实上没有添加任何负值(基于我的知识和我做过的一些测试)

多头是签名整数。在C ++和其他低级语言中,整数类型具有固定大小。当您添加超过它们的最大值时,它们将溢出并回绕到负数。这是由于twos complement的工作原理。

答案 2 :(得分:0)

long可能只是系统上的32位 - 使用uint64_t作为总和 - 这为您提供了保证的64位无符号整数。

#include <cstdint>

uint64_t sumOfPrimes=0;

答案 3 :(得分:0)

检查有效的整数值:Variables. Data Types.

你正在使用signed long,通常是32位,这意味着-2kkk - 2kkk,你可以使用unsigned long,即0-4kkk,或者使用64位{{1} }

如果您需要更大的值2 ^ 64(无符号长long),则需要使用bignum math

答案 4 :(得分:0)

您可以包含标题<cstdint>并使用类型std :: uintmax_t而不是long。