Tom Dara
Tom Dara

Reputation: 61

c++ order of precedence - casting before multiplying

In the C++ function below, why is numbers[max_index1] cast to long long and then multiplied by numbers[max_index2]? I would of thought that you'd multiply the numbers and then cast?

Also would it not make more sense to make the vector numbers type long long instead of int therefore the casting wouldn't be necessary?

long long MaxPairwiseProductFast(const vector<int>& numbers) {

    int n = numbers.size();

    int max_index1 = -1;
    cout << "value at max_index1 is " << numbers[max_index1] << std::endl;
    for(int i = 0; i < n; i++)
        if((max_index1 == -1) || (numbers[i] > numbers[max_index1]))
            max_index1 = i;


    int max_index2 = -1;
    for(int j = 0; j < n; j++)
        if((numbers[j] != numbers[max_index1]) && ((max_index2 == -1) || (numbers[j] > numbers[max_index2])))
            max_index2 = j;

    return ((long long)(numbers[max_index1])) * numbers[max_index2];
}

int main() {
    int n;
    cin >> n;
    vector<int> numbers(n);
    for (int i = 0; i < n; ++i) {
        cin >> numbers[i];
    }

    long long result = MaxPairwiseProductFast(numbers);
    cout << result << "\n";
    return 0;
}

Upvotes: 0

Views: 1895

Answers (2)

Useless
Useless

Reputation: 67852

I woudld of thought that you'd multiply the numbers and then cast?

Imagine your two operands have the value std::numeric_limits<int>::max(). This is the biggest value an int can represent, and (since it's a positive integer) the result of squaring this number is even bigger.

When you multiply two int values, the result is also an int. See here (specifically conversions, integral promotion and overflow of signed types).

Since the result is by definition bigger than the largest value you can store in an int, doing this multiplication with ints gives an undefined result. You need to perform the multiplication with a type large enough to store the result.

Upvotes: 1

Gaurav Sehgal
Gaurav Sehgal

Reputation: 7542

((long long)(numbers[max_index1])) * numbers[max_index2];

numbers[max_index2] will be promoted to long long before multiplication is performed. If you multiply two int's and the result overflowed, there is nothing you can achieve by casting that result to long long, so you cast first, then multiply.

Also would be not make more sense to make the vector numbers type long long instead of int therefore the casting wouldn't be necessary?

If you know that the individual numbers will fit an int, but the result of multiplying two int's can overflow, this will help save space.

Upvotes: 2

Related Questions