lar-ect / plataforma-lop

Plataforma de gerenciamento de exercícios para a disciplina de Lógica de Programação
http://lop.ect.ufrn.br
23 stars 5 forks source link

Bug na divisão inteira #90

Closed Mazuh closed 6 years ago

Mazuh commented 7 years ago

Na lista de funções disponíveis pro usuário, a divisaoInteira(x, y) tem uma falha que precisa ser corrigida.

Essa falha diz respeito a uma má interpretação da função floor, pois ela não serve pra "jogar fora as casas decimais". O JS a implementa de acordo com os livros de Matemática Discreta, e lá a função floor é definida mais ou menos assim:

floor: R -> Z
floor(x) = n; n <= x < n+1

Ou seja, é uma função que converte real em inteiro. E o piso de x é basicamente o inteiro n imediatamente anterior (ou igual) a x. Consequências dessa definição (que refletem no retorno da implementação do divisaoInteira):

Math.floor(1/2) == 0 // pois, nos inteiros: (0) <= (0.5) < ((0)+1)
Math.floor(-1/2) == -1 // pois, nos inteiros: (-1) <= (-0.5) < ((-1)+1)

Esse comportamento inesperado irá provocar bugs "sem explicação" nos códigos dos calouros.

Note que converter de inteiro pra o ponto flutuante da linguagem também pode provocar erros devido a imprecisão (na minha experiência, já tentei fazer o cast explícito de algo como 1.8 + 0.2 e o negócio insistia em retornar 1). Observe também que Math.round seria a mais perigosa e até inútil das opções.

Portanto, creio que pra respeitar o comportamento esperado da função, seja interessante usar o Math.floor para quando o quociente for não negativo, e usar o Math.ceil (a função teto) quando o quociente for negativo. O teto também pode ser representado por ceil(x) = floor(x)+1.

tibuurcio commented 7 years ago

Olá @Mazuh,

Primeiro, muito obrigado por tomar o tempo de cadastrar essa issue super bem explicada! 🎉👏 Se eu puder saber, apenas por curiosidade, como você conheceu o sistema? 😄

A função divisãoInteira já era usada pelos professores antes mesmo da existência do sistema, através de um arquivo javascript que disponibiliza a função para os alunos. Como nós testamos a execução na hora do cadastro das questões, e utilizamos esses valores retornados como resultado dos casos de teste, é provável que não fosse dar problema, mas isso não significa que a execução está certa... Temos que corrigir isso. Sua correção é extremamente válida para todos!

Apesar de simples, antes de modificar qualquer coisa no processo de execução de questões, a issue #41 precisa ser finalizada, pois nós temos quase 100 questões cadastradas atualmente no sistema e precisamos ter certeza que nenhuma caso de teste vai quebrar.

Agradeço mais uma vez pelo tempo dedicado! 👍

Mazuh commented 7 years ago

(off)

Minha namorada Amanda (que fez Técnico em Informática comigo) faz CeT e eu acompanho de longe a movimentação do professor dela no Github. Recentemente ela fez um vídeo explicando uma questão (era um trabalho do prof, ou algo assim) e dizendo que a divisão inteira equivale a só aplicar a floor(). Por coincidência, eu havia tido uma aula da floor numa disciplina matemática essa semana e me assustei na mesma hora com o que ela falou, então vasculhei os códigos até achar essa função e abrir a issue. Achei realmente muito problemática.

Também sou bolsista (CCSA) e também tô tentando trazer o free source aos sistemas da UFRN. Creio que essa transparência (em especial se tratando de conhecimento produzido) é importantíssimo à nossa instituição. Apesar de que eu ainda tô aprendendo a usar a tecnologia lá e sequer temos testes unitários ainda. :P

Mazuh commented 7 years ago

Já tive incontáveis problemas trabalhando com decimais e sei que é uma questão de tempo até alguém quebrar a cabeça por horas tentando entender como a -0.5 é convertido pra -1 enquanto 0.5 é convertido pra 0, haha. Se for em um loop, seria ainda mais difícil de enxergar sem depuração. Seria uma frustração desnecessária.

tibuurcio commented 7 years ago

Entendo... Interessante, irei comentar isso com os professores quando tiver oportunidade.

Obrigado mais uma vez! 👍

orivaldosantana commented 6 years ago

Obrigado @Mazuh por essa contribuição.