Caros prof. Reverbel e Natan,
Constatei dois possíveis problemas no gabarito.
__________________
Problema 1: Excesso de dígitos na resposta 57
O enunciado diz "#define MAX_DIGITOS 50" mas a resposta do exemplo 57 tem 53 dígitos, conforme já indicado pelo colega André (Antonio Andre Monteiro Manoel):
57) 987654321987654321987654321987654321987654321 * 90760300 =
89639802559896102559896102559896102559896102470256300
__________________
Problema 2: Possível erro na resposta 61
Verifiquei os resultados da saida.txt com um pequeno programa em Python, pois esta linguagem possui suporte nativo a inteiros grandes. Percebi que o resultado do último exemplo não é o que acontece em Python.
Daí implementei um pequeno programa em Java, usando java.math.BigInteger, e o resultado é o mesmo do programa em Python.
Veja as saídas dos dois programas. Em cada saída, a linha que começa com 61) é o gabarito do prof. Reverbel e a linha seguinte é a calculada pelo programa:
#################
luciano@stella:~/Documents/usp/repo/mac122/ep1$ ./inteiro_grande.py
61) -123456708912345678901234567890 % 12304567089123405 = -6157816627064550
-123456708912345678901234567890 % 12304567089123405 = 6146750462058855
False
luciano@stella:~/Documents/usp/repo/mac122/ep1$ java InteiroGrande
61) -123456708912345678901234567890 % 12304567089123405 = -6157816627064550
-123456708912345678901234567890 % 12304567089123405 = 6146750462058855
false
#################
No anexo, o fonte dos dois programas em Python e Java.
Prof. Reverbel ou Natan: vocês podem confirmar?
Grato,
Luciano
PS. Suspeito que o problema tenha a ver com o tratamento do sinal. Na prática, o operador % só é útil com operandos inteiros e positivos. Eu nunca vi um uso prático real de % com um operando negativo, porque este operador é comumente usado para verificar o resto de alguma contagem dividido por alguma outra contagem, enfim, sempre lidando com números naturais.
Olá Luciano,
Confirmo o problema na resposta 57. Já a resposta 61 está correta.
Confirmo o problema na resposta 57. Já a resposta 61 está correta.
Você está certo quanto ao fato da dúvida na resposta 61 ser relacionada com o sinal. Quando o dividendo e o divisor têm sinais opostos, há duas maneiras de se definir o resto. Uma possibilidade é convencionar que o resto tem o sinal do dividendo. Outra possibilidade é convencionar que o resto tem o sinal do divisor. Algumas linguagens usam a primeira convenção, outras usam a segunda. A particular convenção adotada não é uma coisa muito importante... Como você observou, são escassos os usos reais do operador % com um operando negativo. Mas de qualquer modo precisamos escolher uma das convenções.
Neste EP resolvemos seguir a convenção que é usada na linguagem C (e também em Java), segundo a qual o resto tem o sinal do dividendo. Desse modo, se você usar a calculadora construída no EP para obter o resto da divisão de dois "inteiros grandes" que não sejam realmente grandes, isto é, dois números que cabem em variáveis tipo int da linguagem C (ou de Java), o resultado será igual ao do operador % da linguagem.
Os BigIntegers de Java também seguem a convenção "resto com o sinal do dividendo". O problema do teste que você anexou (refiro-me ao seu arquivo InteiroGrande.java) é que você usou o método mod, que não devolve o resto. Esse método não é equivalente ao operador % de Java! Para obter o resto (remainder), use o método divideAndRemainder da classe java.math.BigInteger. Refaça seu teste com esse método e você obterá a resposta que está no ítem 61 do arquivo saida.txt.
Reverbel
Neste EP resolvemos seguir a convenção que é usada na linguagem C (e também em Java), segundo a qual o resto tem o sinal do dividendo. Desse modo, se você usar a calculadora construída no EP para obter o resto da divisão de dois "inteiros grandes" que não sejam realmente grandes, isto é, dois números que cabem em variáveis tipo int da linguagem C (ou de Java), o resultado será igual ao do operador % da linguagem.
Os BigIntegers de Java também seguem a convenção "resto com o sinal do dividendo". O problema do teste que você anexou (refiro-me ao seu arquivo InteiroGrande.java) é que você usou o método mod, que não devolve o resto. Esse método não é equivalente ao operador % de Java! Para obter o resto (remainder), use o método divideAndRemainder da classe java.math.BigInteger. Refaça seu teste com esse método e você obterá a resposta que está no ítem 61 do arquivo saida.txt.
Reverbel
Complementando... Este é um trecho da documentação da classe java.math.BigInteger:
"Semantics of arithmetic operations exactly mimic those of Java's integer arithmetic operators, as defined in The Java Language Specification. For example, division by zero throws an
Reverbel
"Semantics of arithmetic operations exactly mimic those of Java's integer arithmetic operators, as defined in The Java Language Specification. For example, division by zero throws an
ArithmeticException
, and division of a negative by a positive yields a negative (or zero) remainder." Reverbel