divisão de número inteiro de arredondamento com negativos em C ++
Pergunta
a
Suponha e b
são ambos do tipo int
e b
é diferente de zero. Considere o resultado da execução a/b
nos seguintes casos:
-
a
eb
são ambos não negativo. -
a
eb
são ambos negativos. - Exatamente um deles é negativo.
No caso 1 o resultado é baixo arredondado para o número inteiro mais próximo. Mas o que significa a palavra padrão sobre Casos 2 e 3? Um projecto de idade eu encontrado flutuando na Internet indica que é dependente de implementação (sim, mesmo caso 2), mas a comissão está inclinando-se para torná-lo sempre em volta para zero. ' Alguém sabe o que o (mais recente) norma diz? Por favor, só responder com base no padrão, não o que faz sentido, ou o que compiladores particulares fazer.
Solução
De acordo com a revisão maio de 2008,
Você tem razão:
O binário / operador proporciona o quociente e o operador binário% origina o resto da divisão da primeira expressão pelo segundo. Se o segundo operando de / ou% é zero o comportamento é indefinido; caso contrário (a / b) * b + a% b é igual a um. Se ambos os operandos são não-negativo, então o restante é não-negativo; se não, o sinal de que o restante é implementação-defined75).
Nota 75 diz:
De acordo com os trabalhos em curso para a revisão da ISO C, o algoritmo preferido para a divisão de número inteiro segue as regras definidas na norma ISO Fortran, ISO / IEC 1539:., 1991, em que o quociente é sempre arredondado para zero
As chances são de que C ++ vai ficar C a este respeito. Tal como está, ela é indefinida, mas eles têm um olho para mudá-lo.
Eu trabalho no mesmo departamento como Stroustrup e com um membro da comissão. As coisas tomam idades para obter realizado, e sua infinita política. Se parece bobo, provavelmente é.
Outras dicas
Como uma atualização para as outras respostas:
O último projecto de C ++ 11, n3242 que é para a maioria dos fins práticos idênticos ao real C ++ 11 padrão, diz esta em 5,6 ponto 4 (página 118):
Para operandos integrais operador / produz o quociente algébrica com qualquer parte fraccionada descartado; (Ver nota 80)
Nota 80 estados (nota que as notas são não-normativa):
80) Este é muitas vezes chamado de truncamento para zero.
O ponto 4 passa a afirmar:
Se o quociente a / b é representável no tipo do resultado, (A / b) * b + a% b é igual a um.
que pode ser mostrado para exigir que o sinal de a%b
ser o mesmo que o sinal de a
(quando não zero).
Às vezes precisamos dar um passo para trás e olhar apenas para a matemática de que:
Dada int x, y int
Se int i1 = x / y e int i2 = x% y
então y * i1 + i2 deve ser x
Portanto, este não é tanto sobre o padrão, mas só há uma maneira isso pode possivelmente ser. Se todos os padrões permite que ele seja de outra maneira, então o padrão está errado, e isso significa a língua é quebrado.