Duvida usando o operador modulo no c++ [RESOLVIDO]

1. Duvida usando o operador modulo no c++ [RESOLVIDO]

Perfil removido
removido

(usa Nenhuma)

Enviado em 24/01/2017 - 17:50h

cout << -7 % 26 << endl; 

Pq isso me retorna -7 ao invés de 19 ? existe alguma maneira de contornar isso ?


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 25/01/2017 - 03:51h

O operador % do C e do C++ é um operador de cálculo de resto de divisão inteira, não de aritmética modular.

Ele é definido da seguinte forma: x%d, sendo x e d inteiros, tem de dar como resultado um valor r tal que x==(x/d)*d+r para quaisquer valores válidos de x e d.

Como se pode ver, a definição acima usa o resultado da divisão inteira. E qual é a definição da divisão inteira, especialmente quando há operandos negativos?

Aí é que mora o perigo. Nas primeiras versões do C (antes do padrão de 1999), cada implementação escolhia o que fazer. Algumas implementações arredondavam sempre no sentido do valor mais próximo de zero (por exemplo: 7/5==1 e (-7)/5==-1), mas outras poderiam arredondar sempre para baixo (por exemplo: 7/5==1 e (-7)/5==-2, já que -2 é o maior valor inteiro menor que o resultado aritmético -1.4). Se a implementação escolhesse arredondar sempre para baixo, então o comportamento do operador % se parecia mais com o que se tem em aritmética modular (e.g. (-7)%5==3, pois (-7)/5==-2, e -7==(-2)*5+3).

No entanto, a partir do padrão do C de 1999, formalizou-se que a divisão inteira deveria produzir resultados estáveis em qualquer implementação, passando a se requerer sempre o arredondamento para zero. Com a estabilização do comportamento da divisão, também o resultado da aplicação do operador % passou a ser estável.

No caso do C++, os padrões têm seguido as convenções dos padrões do C que vigoravam na data de homologação dos padrões do C++. Na época do primeiro padrão do C++, de 1998, o padrão em vigor do C ainda era o de 1989/1990, logo cada implementação escolhia suas próprias regras de arredondamento. No padrão de 2011, seguiu-se a convenção do C aplicada a partir de 1999, de arredondar sempre no sentido do zero.

Se você quiser uma função módulo mesmo, e que funcione de modo estável com qualquer versão do C ou do C++, terá de escrever uma, semelhante à que vai abaixo.

int mod(int x, int d){
int abs_r=abs(x)%abs(d);
bool x_neg=x<0, d_neg=d<0;
return
x_neg?
d_neg? -abs_r: d-abs_r
:
d_neg? abs_r+d: abs_r
;
}


Note, porém, que essa função não necessariamente vai satisfazer o resultado x==(x/d)*d+mod(x, d).





Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts