## 1. Descrição de vários casos de teste para todas as funções
## 2. Explicação sucinta do funcionamento de cada função
## 3. Estratégias utilizadas na implementação das funções da alínea 2
### Aux Functions
carry
Criamos uma função para passar todos os carries para o dígito de potência superior. Ex. [7,9,11,4,5] -> [7,9,1,5,5]
defaulter
Usamos uma função para retirar todos os 0s a mais. Ex. somaBN [0,0,0,1] [9,9,-9] -> [0,0,0,1] [9,9,-9,0] -> [-1,-1,-1,1] -> [1,0,0,0] -> [1]
extender
Nós extendemos o comprimento do menor BigNumber na soma e subtração até terem os dois o mesmo comprimento para possiblitar a utilização de zipWith nas listas. Ex. [1,2,3,4,5] [6,7,8] -> [1,2,3,4,5] [6,7,8,0,0]
multPrep
Usamos esta função para dar a cada dígito o seu verdadeiro valor para ajudar na multiplicação e divisão. Ex. [1,2,3,4] -> [1,20,300,4000]
signExtender
Esta função aplica o sinal do digito de mais valor do BigBumber a todos os outros. Ex. [1,2,3,4] -> [1,2,3,4], [5,6,7,-8] -> [-5,-6,-7,-8,]
negateBN
Altera o sinal do BigNumber. Ex. [1,2,3,4] -> [1,2,3,-4], [1,-2] -> [1,2]
### scanner
Faz read de todos os char da string para uma lista com a ordem inversa retirando os espaços. Ex. "123 456" -> [6,5,4,3,2,1]
Se o primeiro char da string for '-' utiliza a função negateBN para trocar o sinal no fim da tradução para BigNumber . Ex. "-1234" -> [4,3,2,-1]
### output
Faz print de cada dígito do BigNumber por ordem inversa. Ex. [1,2,3,4,5] -> "54321"
### somaBN/subBN
Como subtrair é o mesmo que somar o negativo usamos essa estratégia no subBN logo tudo o que se aplica ao somaBN aplica-se também ao subBN. Ex. subBN [7,1] [3] -> somaBN [7,1] [-3]
Depois utilizamos a função zipWith (+) para somar todos os digitos com a mesma potência de 10. Ex. [1,2,3,4,5] [6,7,8,0,0] -> [7,9,11,4,5]
Para evitar trocas de sinais e facilitar cálculos criámos algumas condições com diferentes formas de somar.
x<0 y<0 inverte ambos os sinais e inverte o sinal do resultado. Ex. sumBN [0,-1] [-3] -> [0,1] [3] -> [3,1] -> [3,-1]
x<0 y>=0 -x>y passa x para positivo e todos os digitos de y para negativo. Ex. sumBN [0,0,-1] [2,5] -> sumBN [0,0,1] [-2,-5]
x>=0 y<0 x<-y passa y para positivo e todos os digitos de x para negativo. Ex. sumBN [2,5] [0,0,-1] -> sumBN [-2,-5] [0,0,1]
x*y<0, o BigNumber positivo é de maior valor que o negativo, o BigNumber que for negativo fica com todos os dígitos negativos. Ex. somaBN [0,0,0,1] [1,2,-1] -> [0,0,0,1] [-1,-2,-1] -> [9,7,8]
else soma os dois BigNumber. Ex. somaBN [0,1] [2] -> [2,1]
### mulBN
Criamos condições para evitar números negativos
x<0 y<0 inverte ambos os sinais e o resultado é positivo. Ex. mulBN [-3] [-2] -> mulBN [3] [2] -> [6]
x<0 y>0 inverte o sinal de x e inverte o sinal do resultado. Ex. mulBN [-3] [2] -> mulBN [3] [2] -> [6] -> [-6]
x>0 y<0 inverte o sinal de y e inverte o sinal do resultado. Ex. mulBN [3] [-2] -> mulBN [3] [2] -> [6] -> [-6]
x>0 y>0 faz a multiplicação normal. Ex. mulBN [3] [2] -> [6]
Chamamos a função recursivamente com um acumulador no resultado que é a soma do acumulador com a multiplicação de cada digito de y com cada um de x. Utilizamos também a função auxiliar multPrep e a função auxiliar carry. Ex. mulBN [1,1,1] [2,3] -> [1,1,1] [2,30] -> [1,1,1] [30] [2,2,2] -> [32,32,32] -> [2,5,5,3]
## 4. Resposta à alínea 4
### Int
Como o valor de Int é guardado num container de 64 bits o valor máximo (maxBound) de um Int é 2^63 = 9223372036854775808 pois é guardado em posições de memória de 64 bbb, o elemento 92 da sequência de fibonacci tem o valor 7540113804746346429 e é assim o valor máximo permitido da sequência de fibonacci sem haver overflow. O elemento 93 da sequência tem o valor 12200160415121876738 que ultrapassa o limite permitido para Int mostrando o valor -6246583658587674878.
### Integer
Como o tipo Integer não tem limite de valor ele apenas tem o limite da memória da máquina onde corremos o programa. Assim sendo conseguimos facilmente atingir elementos da sequência de fibonacci na ordem dos milhões
### BigNumber
O limite para o tamanho de uma lista depende da memória da máquina onde se corre o programa pois cada elemento ocupa uma posição de memória diferente. Como estamos a usar uma lista de Int cada elemento da lista tem o valor máximo de 2^63, no entanto o valor máximo de cada elemento da lista será 9 pois cada dígito terá a sua posição na lista.
Assim sendo o elemento de valor mais elevado o cálculo da sequ