Умножение на 1 миллион

#c #long-integer

#c #длинное целое число

Вопрос:

Почему, когда вы это делаете:

 int a = 1000000 , b = 1000000;
long long product = a * b;
cout<<product;
 

Это дает какое-то случайное значение мусора?Почему и a, и b должны быть long long для его вычисления?

Комментарии:

1. Потому что int не может хранить произведение умножения. Проверьте geeksforgeeks.org/c-data-types размеры типов данных для получения дополнительной информации. Int может содержать максимальное значение 2147483647

2. An int имеет ограниченное количество битов, и вы переполняете целое число со знаком и вводите неопределенное поведение в вашей программе. Значение корзины с таким же успехом могло быть «smurf». Проверьте основные типы

3. int op int дает int. Один из двух должен быть long long, чтобы другой был повышен до long long .

4. Значение не случайное, а по модулю 2 ^ 32

5. Таким образом, практически говоря, результат очень хорошо воспроизводим…. Итак, «случайный» — это плохая формулировка

Ответ №1:

Вы наблюдаете последствия неопределенного поведения. Это:

 a * b   
 

является (арифметическим) выражением типа int , поскольку оба операнда a и b имеют тип int . Попытка сохранить значение 1000000000000 в an int приводит к так называемому переполнению целых чисел со знаком, которое является неопределенным поведением.

Либо приведите один из операндов к long long , что приведет к тому, что все выражение станет long long достаточно большим, чтобы принять значение 1000000000000:

 #include <iostream>

int main()
{
    int a = 1000000, b = 1000000;
    auto product = static_cast<long long>(a) * b;
    std::cout << product;
}
 

Или определите один из операндов как long long :

 #include <iostream>

int main()
{
    long long a = 1000000;
    int b = 1000000;
    auto product = a * b;
    std::cout << product;
}
 

При необходимости используйте unsigned long вместо.

Комментарии:

1. О, так значит, когда вы умножаете два целых числа, значение также будет сохранено внутри целого числа?

2. @cosmin-andreiparaschiv неявные преобразования — Проверьте части продвижения .

Ответ №2:

Это будет работать нормально. Когда вы выполняете умножение int и int если оно выходит за пределы, то, чтобы поместить его в длинную длинную переменную, вы умножаете результат на 1ll или 1LL . При умножении результата на 1ll результат преобразуется в long long во время вычисления самого продукта.

 int a = 1000000 , b = 1000000;
    
long long product = 1ll * a * b;
    
cout << product;
 

Комментарии:

1. Приведение хотя бы одного из int s к a long long также сработало бы, предполагая, что у нас нет 16-битной int проблемы с самого начала.

2. Обратите внимание, что умножение на 1ll не является приведением. Фактическое приведение будет использовать static_cast<long long>(a) или C-стиль (long long) a