1

Why do I get an INT overflow error when assigning a long value to 'out[0]' in the following code? I have declared out as a vector already.

vector<long long> foo(int m, int n) {
        vector<long long> out(5);
        // why is there an overflow of int ?? 
        out[0] = (m-1)*(n-1);
        cout << out[0] << endl;

        out[0] = (long long) (m-1)*(n-1);
        cout << out[0] << endl;
        ..
        ..
        return out;
}

I also found that typecasting the RHS works. But I'm not sure that is the intended way to assign 'long long' values.

COUT: 
-615099295
3679868001
For values: m=40000 and n=92000

Please help me understand why I can't assign a value to the index normally, and what is the proper way of doing so. (I know this might be a newbie question, but I couldn't find much about this.)

I needed to assign values to this output vector using a map in my code, which I found out was returning garbage, and only after a good time spent debugging, I found a problem with the initial assignment itself.

Upon reviewing the SO related questions I found that LL needs to be mentioned after the number, but how do I do that with an expression of int variables?

Antact
  • 59
  • 6
  • 2
    Please read [ask] with a [mcve]. All code should be in the questions as formatted text, not images or links. – Richard Critten Jul 09 '23 at 10:50
  • Clue: you're not casting the entire right-hand side. – molbdnilo Jul 09 '23 at 10:51
  • @RichardCritten Thanks. Edited my question to make those changes. – Antact Jul 09 '23 at 10:57
  • `(m-1)*(n-1)` is evaluated using integer arithmetic. One solution: cast both `m` and `n` to `long long`. – Paul Sanders Jul 09 '23 at 11:05
  • When you only want to do `long long` calculations with `m` and `n` and never a calculation in `int`, then the types of the parameters should be `long long` – mch Jul 09 '23 at 11:21
  • Read the documentation on [`std::vector::operator[]`](https://en.cppreference.com/w/cpp/container/vector/operator_at) and you will see it doesn't accept an `int` but a `std::size_t` which is an unsigned integer. `LL` is NOT a C++ type it is often defined by a macro which is a bad habit seen on competitive coding sites as is the use of indeiscriminate use of `long long` in the hope that will fix issues where `std::size_t` should be used. Side note : stop using `using namespace std;` it looks like you are already picking up some bad habits. – Pepijn Kramer Jul 09 '23 at 11:21
  • Tip :Good sources to learn cpp from are : A [recent C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) or have a go at https://www.learncpp.com/ (that's pretty decent, and pretty up-to-date). For C++ reference material use : [cppreference](https://en.cppreference.com/w/). And after you learned the C++ basics from those sources, look at the [C++ coreguidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines) regularely to keep up-to-date with the latest guidelines. – Pepijn Kramer Jul 09 '23 at 11:23
  • @molbdnilo `out[0] = (long long) (m-1)*(n-1);` is sufficient. `(n-1)` is implicitly converted to `long long`. – Ted Lyngmo Jul 09 '23 at 11:43
  • @TedLyngmo Yes, my point was that `(long long) ((m-1)*(n-1))` would produce the unexpected "wrong" result. – molbdnilo Jul 09 '23 at 13:36
  • @molbdnilo Aha, ok, got it. – Ted Lyngmo Jul 09 '23 at 13:39

1 Answers1

6

In ...

out[0] = (m-1)*(n-1);

... you perform the multiplication using int. It doesn't matter that out[0] is a long long&. The conversion to long long happens after the multiplication has been performed.

When you cast m - 1 to long long then n - 1 will also be implicitly converted to long long and the multiplication is then done using long long.

In modern (C++11 or later) C++, it's preferable to use static_cast<long long> instead of the old style (long long) though:

out[0] = static_cast<long long>(m-1) * (n-1);

I also found that typecasting the RHS works. But I'm not sure that is the intended way to assign 'long long' values.

You cast the LHS operand in the multiplication and it doesn't matter if you cast LHS, RHS or both to long long. As long as you cast at least one of them, the other operand will follow.

Yes, in situations like this, it's the correct way. Another way would be to change the type of m and n to long long.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108