I am having an issue with a program I am trying to write, which will take the product of numbers in an array. I'm getting random numbers from the array appended to my output, and can't figure why. Please help.
> I'm getting random numbers from the array appended to my output, and can't figure why.
When we multiply those twenty integers, the result may be too large to be held in an integer.
We have to avoid that (undefined behaviour).
Either check for integer overflow while computing the product,
or to get an approximate result, use a floating point type (double) to hold the product.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <limits>
constint MINV = -100 ;
constint MAXV = 100 ;
constint N = 20 ;
using array_type = int[N] ; // 'array_type' is an alias for 'array of N int'
void print( const array_type& array ) { // the array is passed by reference to const
std::cout << "\n[ " ;
// range based loop: http://www.stroustrup.com/C++11FAQ.html#forfor( int v : array ) std::cout << v << ' ' ;
std::cout << "]\n" ;
}
void gen_rand_array_fill( array_type& array ) { // the array is passed by reference
for( int& v : array ) {
v = rand() % (MAXV+1);
if( rand()%2 == 1 ) v = -v ;
}
}
void calc_and_print_product( const array_type& array ) {
std::cout << "\nProduct of numbers: " ;
// if there is a zero in the array, the product is zero
for( int v : array ) if( v == 0 ) {
std::cout << "0\n" ;
return ;
}
// largest and smallest values that product can hold
constexprlonglong ubound = std::numeric_limits<longlong>::max() ;
constexprlonglong lbound = std::numeric_limits<longlong>::min() ;
longlong product = 1 ;
for( int v : array ) {
// check if there would be an integer overflow
constdouble result = product * double(v) ;
if( result > ubound || result < lbound ) {
std::cout << "integer overflow!\n" ;
return ;
}
else product *= v ; // multiply only if there is no overflow
}
std::cout << product << '\n' ;
}
int calc_min( const array_type& array ) {
int minimum_value = MAXV ;
for( int v : array ) if( v < minimum_value ) minimum_value = v ;
return minimum_value;
}
int get_int( int min_value, int max_value ) {
std::cout << "enter an integer in [" << min_value << ',' << max_value << "]: " ;
int number ;
if( std::cin >> number && number >= min_value && number <= max_value ) return number ;
std::cout << "invalid input. try again.\n" ;
// the stream will be in a failed state if the user entered a non-number eg. 'xyz'
std::cin.clear() ; // clear the possible failed state
std::cin.ignore( 1000, '\n' ) ; // and throw the bad input away
return get_int( min_value, max_value ) ; // try again
}
void input( array_type& array ) {
std::cout << "Input " << N << " numbers from " << MINV << " to " << MAXV << '\n' ;
for( int& v : array ) v = get_int( MINV, MAXV ) ;
}
int main()
{
std::srand( std::time(nullptr) ) ; // once, at the start of the program
array_type array ;
std::cout << "PROJECT 1\nPART I\nInput numbers or generate randomly?\n\t1) Input numbers\n\t2) Generate randomly\n? ";
constint input_or_gen = get_int( 0, 1 ) ;
if( input_or_gen == 0 ) input(array) ;
else gen_rand_array_fill(array) ;
print(array) ;
calc_and_print_product(array) ;
std::cout << "Minimum value: " << calc_min(array) << '\n' ;
}