Melhor resposta
Primeiro, uma reclamação: C e C ++ são duas linguagens diferentes. A resposta abaixo aplica-se a ambos, mas às vezes a resposta difere entre os idiomas. E, em ambos os idiomas, a expressão c/c++
tem comportamento indefinido.
Este é um maneira idiota de conseguir uma promoção de tipo. Observe que o exemplo nos detalhes é formulado de forma mais clara:
int a, b;
long long l = a * 1ll * b;
Conforme observa o OP, o 1ll
declara um long long
literal inteiro.
É presença aqui no código promove toda a multiplicação para long long
por meio das conversões aritméticas usuais, particularmente as promoções de inteiros.
A expressão é analisada como ((a * 1ll) * b)
. A primeira multiplicação retorna apenas o valor de a
como um long long
. A segunda multiplicação também é atualizada para long long
.
Você poderia ter obtido o mesmo efeito com um elenco explícito:
int a, b;
long long l = (long long)a * b;
É um pouco mais de digitação, mas apenas um pouco. A segunda formulação é certamente mais clara, pelo menos para mim.
Você também pode fazer algo como:
long long l = a;
l *= b;
Mas isso está começando a ficar bobo de novo.
E por que você precisa se promover? Se você tiver valores grandes o suficiente, a multiplicação pode transbordar. Ao promover para long long
, você garante que não o fará.
Vamos supor int
e 64- bit long long
, e representação de complemento de 2. O maior produto que você pode obter é -2 ^ {31} \ times -2 ^ {31} = 2 ^ {62}. Isso está abaixo do maior valor positivo que você pode representar, 2 ^ {63} – 1, então você tem a garantia de que não vai estourar.
Resposta
aeb são int int * int -> int (todos no intervalo de 32 bits int ou seja, -2147483648 int 2147483647) . “. 2147483647 * 2 = -2 e não 4294967294 operador de atribuição tem associatividade da direita para a esquerda ou seja, na expressão: long long l = a * b; a * b é calculado primeiro int * int-> int se a = 2147483647 eb = 2 a * b -> – 2 e não 4294967294 agora l = -2 -2 é convertido em long long e armazenado em l