-2

I don't get why the summation never works properly, yet sums consistently. It dosent throw any errors, but never gets the correct result. According to wolfram|alpha i can be off with as much as 20 000 000 000 for large calculations. I have no idea why this happens, so any ideas you might have are greatly appreciated! Note: Compiled with -O3 and -std=c++14 flags.

Code:

#include "stdafx.h"
#include <math.h>
#include <vector>
#include <stdio.h>
#include <iostream>
typedef unsigned long long ul;
const ul PRIMES = 1000000;
bool isPrime(ul n)
{
    if (n <= 1) return false;
    double sqN = sqrt(n);
    for (ul i = 3; i <= sqN; i++) {
        if ((int)n % i == 0) return false;
    } return true;
}
int main()
{
    std::vector<ul> primes;
    ul sumPrimes = 0;
    ul numPrimes = 0;
    for (ul n = 2; n <= PRIMES; n++) if (isPrime(n)) primes.push_back(n);
    numPrimes = primes.size();
    for (ul sp : primes) sumPrimes += sp;
    std::vector<ul> fizz, buzz, fizzbuzz;
    ul sumF = 0, sumB = 0, sumFB = 0;
    ul numF = 0, numB = 0, numFB = 0;
    for (ul prime = 0; prime < primes.size(); prime++) {
        if (prime % 15 == 0) {
            fizzbuzz.push_back(primes[prime]);
        }
        else if (prime % 5 == 0) {
            buzz.push_back(primes[prime]);
        }
        else if (prime % 3 == 0) {
            fizz.push_back(primes[prime]);
        }
    }
    for (ul fb : fizzbuzz) sumFB += fb;
    for (ul f : fizz) sumF += f;
    for (ul b : buzz) sumB += b;
    numF = fizz.size(); numB = buzz.size(); numFB = fizzbuzz.size();
    std::cout << "Stats for primes upto\t" << PRIMES << "\n";
    std::cout << "Primecount:\t\t" << numPrimes << "\n";
    std::cout << "Sum Primes:\t\t" << sumPrimes << "\n";
    std::cout << "Fizzcount:\t\t" << numF << "\n";
    std::cout << "Sum Fizz:\t\t" << sumF << "\n";
    std::cout << "Buzzcount:\t\t" << numB << "\n";
    std::cout << "Sum Buzz:\t\t" << sumB << "\n";
    std::cout << "FizzBuzzcount:\t\t" << numFB << "\n";
    std::cout << "Sum FizzBuzz:\t\t" << sumFB << "\n";
    std::system("pause");
    return 0;
}

And this is the output i get: output

ZxZ
  • 1
  • 2
  • 3
    Does it fail any specific test case or does it fail them all? If it fails them all take the simplest/smallest test case and run it through your code with a debugger to see where it falls apart. – NathanOliver Apr 10 '17 at 13:28
  • 3
    In `isPrime`, don't convert the input argument (whose type is `unsigned long long`) to `int`. Get rid of that cast. – Pete Becker Apr 10 '17 at 13:29
  • 1
    Why are you starting at %3 ? numbers that are %2 == 0 are not prime either – Ryan Murphy Apr 10 '17 at 13:30
  • What result are you expecting from fizzbuzzing *prime numbers*? – molbdnilo Apr 10 '17 at 13:33
  • Some [elementary testing](http://ideone.com/ln82Ho) reveals rather strange results. You just assumed that `isPrime` was correct, didn't you? – molbdnilo Apr 10 '17 at 13:39
  • Also, what is the point checking whether a prime number is exactly divisible by anything other than 1 and itself? By definition (assuming a correct implementation) it won't be, so you'll just add the numbers 15, 5 and 3 to your vectors. – Steve Kidd Apr 10 '17 at 13:41
  • @SteveKidd He checks **index** `prime` for dividing by 15, 5 and 3, but not `primes[prime]` – borisbn Apr 10 '17 at 13:44
  • @borisbn Oops, Quite right - variable could be better named. – Steve Kidd Apr 10 '17 at 13:47

1 Answers1

1

In your isPrime method, you are starting with i = 3. Start with i = 2 so that you are removing non primes that have a factor of 2.

bool isPrime(ul n)
{
    if (n <= 1) return false;
    double sqN = sqrt(n);
    for (ul i = 3; i <= sqN; i++) {
        if ((int)n % i == 0) return false;
    } return true;
}

Try

bool isPrime(ul n)
{
    if (n <= 1) return false;
    double sqN = sqrt(n);
    for (ul i = 2; i <= sqN; i++) {
        if ((int)n % i == 0) return false;
    } return true;
}

Unless I have misunderstood something.

Ryan Murphy
  • 842
  • 1
  • 9
  • 20