Что не так с присвоением длинного значения индексу всего вектора? Переполнение INT в векторе <long long>

Почему я получаю ошибку переполнения 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?

Пожалуйста, прочитайте Как спросить с минимально воспроизводимым примером. Весь код должен быть в вопросах в виде форматированного текста, а не изображений или ссылок.

Richard Critten 09.07.2023 12:50

Подсказка: вы не используете всю правую сторону.

molbdnilo 09.07.2023 12:51

@RichardCritten Спасибо. Отредактировал мой вопрос, чтобы внести эти изменения.

Antact 09.07.2023 12:57
(m-1)*(n-1) оценивается с помощью целочисленной арифметики. Одно решение: привести и m, и n к long long.
Paul Sanders 09.07.2023 13:05

Если вы хотите выполнять только long long расчеты с m и n и никогда не выполнять расчеты с int, то типы параметров должны быть long long

mch 09.07.2023 13:21

Прочтите документацию по std::vector::operator[], и вы увидите, что она принимает не int, а std::size_t, которое является целым числом без знака. LL НЕ является типом C++, он часто определяется макросом, что является плохой привычкой, наблюдаемой на сайтах конкурентного кодирования, как и использование неразборчивого использования long long в надежде, что это решит проблемы, где std::size_t следует использовать. Примечание: прекратите использовать using namespace std;, похоже, вы уже приобрели некоторые вредные привычки.

Pepijn Kramer 09.07.2023 13:21

@molbdnilo out[0] = (long long) (m-1)*(n-1); достаточно. (n-1) неявно преобразуется в long long.

Ted Lyngmo 09.07.2023 13:43

@TedLyngmo Да, я имел в виду, что (long long) ((m-1)*(n-1)) приведет к неожиданному «неправильному» результату.

molbdnilo 09.07.2023 15:36

@molbdnilo Ага, хорошо, понял.

Ted Lyngmo 09.07.2023 15:39
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
10
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В ...

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.

Другие вопросы по теме