2017-02-22 13 views
2

Я читал, что преобразование от int к long long int является продвижением по службе и, следовательно, считается, что не должно быть никаких проблем, поскольку нет потери данных, в отличие от преобразования наоборот.Почему неявное преобразование int в long long int дает неожиданный ответ на C++?

Но когда я умножаю два int s большой ценности и храните его в long long int, он показывает мне отрицательное число.

Например:

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

Приведенный выше код дает мне отрицательное значение. Может кто-нибудь объяснить, почему?

+1

Это потому, что вы используете ints для выполнения операции, которая приводит к возвращаемому значению, которое также является int, которое может переполняться, а затем у вас есть продвижение, которое уже слишком поздно. –

+0

Я пробовал то же самое с C, где я использовал «% lld» placeholder в printf для печати. Даже тогда это показывает мне отрицательную ценность. – Bharg

+2

возможно дубликат http://stackoverflow.com/questions/31662792/multiplication-of-two-integers-in-c – Ap31

ответ

5

Умножение происходит как int, которое переполняет, давая Undefined Behaviour (в данном случае переполнения, что очень нормально - вашей комбинации компилятора + настройки может даже гарантировать его), и после этого результат преобразуется до long long.

Я думаю, что вы хотите сделать преобразование на один из аргументов перед тем умножения, так что умножение выполняется с использованием long long S:

long long c = static_cast<long long>(a)*b; 

Таким образом, b будет повышен до long long до того происходит умножение, и вся операция будет выполнена безопасно и с желаемым результатом.

+0

Переполнение дает неопределенное поведение? –

+3

@Adrian Lis для целых чисел со знаком, да – Ap31

+1

Он определен для 'unsigned int', но не для подписанных. – BoBTFish

7

a*b по-прежнему типа int. После его оценки результат затем преобразован в long long int. В этот момент слишком поздно, чтобы избежать переполнения. Преобразуйте одно из ваших значений в long long int перед тем, как выполнить умножение. Попробуйте это:

#include <iostream> 
using std::cout; 
int main() 
{ 
    int a = 1000000, b = 1000000; 
    long long int c = static_cast<long long int>(a)*b; 
    cout << c; 
    return 0; 
}; 
0

Поскольку умножение двух int сек приведет к другому int, который поставляется со всеми проблемами переполнения прикрепленными. Этот int затем (после факта) продвигается до long long int, что по-прежнему означает, что это не то, что вы хотите.

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

Смежные вопросы