Long multiplication is wrong.

Hello, I'm trying to calculate big numbers but it's not working. I turned every variable into long and switched my project to x64. Here is my code. Thanks!

1
2
3
4
5
6
7
8
9
inline unsigned long calculatePossibleCombinations(unsigned long slots, unsigned long elements) {

	unsigned long possible_combinations = 1;

	for (int i = 0; i < slots; i++)
		possible_combinations *= elements;

	return possible_combinations;
}


Inputs are slots=7 and elements=30
Last edited on
Your title says you are trying to do a long multiplication. You are, however, calculating 30 ^ 7. Is that what you are meaning to do? That answer would be 21,870,000,000.

=If you are trying to calculate 30 * 7, you need to add elements to possible_combinations every time through the loop.

Of course, if you actually are trying to calculate 30 ^ 7 and your system uses a 32-bit unsigned long, the maximum value that a 32-bit unsigned long can contain is 4,294,967,295
What does "not working mean"? Be specific. Is it giving some random junk number? Is your logic simply wrong? What is your expected output?

You're trying to find the number of ways to put N elements in M boxes, right? The answer is not as simple as M^N. I believe you want to use the formula in this link: https://math.stackexchange.com/a/192671
Your formula is is not doing this.

On line 5 you are comparing an int to an unsigned long, but this only produces a warning (and I don't think is the actual problem).

If it isn't the logic of the function that's wrong, I think the real error happens in how you're calling it.

Here's how I tested your code, btw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
inline unsigned long calculatePossibleCombinations(unsigned long slots, unsigned long elements) {

	unsigned long possible_combinations = 1;

	for (unsigned long i = 0; i < slots; i++)
		possible_combinations *= elements;

	return possible_combinations;
}

#include <iostream>
#include <limits>

int main()
{
    std::cout << calculatePossibleCombinations(6, 10) << std::endl;
    std::cout << calculatePossibleCombinations(7, 20) << std::endl;
    std::cout << calculatePossibleCombinations(7, 30) << std::endl;
    std::cout << std::numeric_limits<unsigned long>::max() << std::endl;
}
Last edited on
For slots=7 and elements=30, we can get by with unsigned long long

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

unsigned long long calculatePossibleCombinations( unsigned long long slots, unsigned long long elements )
{
    unsigned long long possible_combinations = 1 ;

    for( unsigned long long i = 0; i < slots ; ++i ) possible_combinations *= elements ;

    return possible_combinations ;
}

int main()
{
    std::cout << calculatePossibleCombinations( 7, 30 ) << '\n' ; // 21870000000
}

http://coliru.stacked-crooked.com/a/cf906aed02133aac


For very large numbers we would need a large integer type of some kind.
For example, using boost::multiprecision::cpp_int

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>

// http://www.boost.org/doc/libs/1_66_0/libs/multiprecision/doc/html/boost_multiprecision/tut/ints.html
using big_int = boost::multiprecision::cpp_int ;

big_int calculatePossibleCombinations( unsigned long slots, unsigned long elements )
{
    big_int possible_combinations = 1 ;

    for( unsigned long long i = 0; i < slots ; ++i ) possible_combinations *= elements ;

    return possible_combinations ;
}

int main()
{
    std::cout << calculatePossibleCombinations( 7, 30 ) << '\n' // 21870000000
              << calculatePossibleCombinations( 73, 308 ) << '\n' ; // a big number
}

http://coliru.stacked-crooked.com/a/51045674deb32991
By wrong I mean
my code outputs 395163520
but calculator on windows outputs 21870000000
what does this program output for you?
1
2
3
4
5
6
7
8
#include <iostream>
#include <limits>

int main()
{
    std::cout << std::numeric_limits<unsigned long>::max() << std::endl;
    std::cout << std::numeric_limits<unsigned long long>::max() << std::endl;
}


Might be that your unsigned long is only 32-bit, but unsigned long long is correctly 64-bit. If your unsigned long long isn't big enough to hold your number, you're going to have to use big ints, as JLBorges suggests.
4294967295
18446744073709551615

I replaced unsigned long with unsigned long long and it worked. But if slot is 14 and elements 27, the same thing happens again....
Last edited on
Yep, it would appear your unsigned long is only 32-bit (4294967295 = 232 - 1). Change your initial program to use unsigned long long instead of unsigned long.

I replaced unsigned long with unsigned long long and it worked. But if slot is 14 and elements 27, the same thing happens again....

1427 > 2102
You're working with numbers larger than 64-bit. I'm afraid you'll have to use a Big Integer library such as boost::multiprecision::cpp_int. See JLBorges's post.

Last edited on
Thank you very much!
Registered users can post here. Sign in or register to post.