Почему я получаю ошибку переполнения INT при присвоении длинного значения «out[0]» в следующем коде? Я уже объявил себя вектором.
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;
}
Я также обнаружил, что приведение типов RHS работает. Но я не уверен, что это предполагаемый способ присвоения значений «long long».
COUT:
-615099295
3679868001
For values: m=40000 and n=92000
Пожалуйста, помогите мне понять, почему я не могу нормально присвоить значение индексу и как это сделать правильно. (Я знаю, что это может быть вопрос новичка, но я не мог найти много об этом.)
Мне нужно было присвоить значения этому выходному вектору, используя карту в моем коде, который, как я обнаружил, возвращал мусор, и только после хорошего времени, потраченного на отладку, я обнаружил проблему с самим начальным назначением.
Изучив вопросы, связанные с SO, я обнаружил, что LL нужно упоминать после числа, но как мне это сделать с выражением переменных int?
Подсказка: вы не используете всю правую сторону.
@RichardCritten Спасибо. Отредактировал мой вопрос, чтобы внести эти изменения.
(m-1)*(n-1) оценивается с помощью целочисленной арифметики. Одно решение: привести и m, и n к long long.
Если вы хотите выполнять только long long расчеты с m и n и никогда не выполнять расчеты с int, то типы параметров должны быть long long
Прочтите документацию по std::vector::operator[], и вы увидите, что она принимает не int, а std::size_t, которое является целым числом без знака. LL НЕ является типом C++, он часто определяется макросом, что является плохой привычкой, наблюдаемой на сайтах конкурентного кодирования, как и использование неразборчивого использования long long в надежде, что это решит проблемы, где std::size_t следует использовать. Примечание: прекратите использовать using namespace std;, похоже, вы уже приобрели некоторые вредные привычки.
Совет: Хорошие источники для изучения cpp: недавняя книга по C++ или попробуйте Learncpp.com (это довольно прилично и довольно актуально). Для справочных материалов по C++ используйте: cppreference . И после того, как вы изучите основы C++ из этих источников, регулярно просматривайте C++ coreguidelines, чтобы быть в курсе последних рекомендаций.
@molbdnilo out[0] = (long long) (m-1)*(n-1); достаточно. (n-1) неявно преобразуется в long long.
@TedLyngmo Да, я имел в виду, что (long long) ((m-1)*(n-1)) приведет к неожиданному «неправильному» результату.
@molbdnilo Ага, хорошо, понял.





В ...
out[0] = (m-1)*(n-1);
... вы выполняете умножение, используя int. Неважно, что out[0] — это long long&. Преобразование в long long происходит после выполнения умножения.
Когда вы приводите m - 1 к long long, тогда n - 1 также будет неявно преобразовано в long long, а затем умножение выполняется с использованием long long.
Однако в современном (C++11 или более позднем) C++ предпочтительнее использовать static_cast<long long> вместо старого стиля (long long):
out[0] = static_cast<long long>(m-1) * (n-1);
Я также обнаружил, что приведение типов RHS работает. Но я не уверен, что это предполагаемый способ присвоения значений «long long».
Вы приводите левый операнд при умножении, и не имеет значения, приводите ли вы левый, правый или оба операнда к long long. Пока вы разыгрываете хотя бы один из них, за ним следует другой операнд.
Да, в таких ситуациях это правильный путь. Другой способ — изменить тип m и n на long long.
Пожалуйста, прочитайте Как спросить с минимально воспроизводимым примером. Весь код должен быть в вопросах в виде форматированного текста, а не изображений или ссылок.