ime_2/Exercícios/03 - Logaritmos/Logaritmos.md

95 lines
3.2 KiB
Markdown
Raw Normal View History

2023-02-12 00:42:14 +01:00
# Logaritmos
## Exercícios 2
**1.** Prove os dois invariantes da primeira versão da função lg:
```c
int lg (int N)
{
int i, n;
i = 0;
n = 1;
while (n <= N/2) {
n = 2 * n;
i += 1;
}
return i;
}
```
Um invariante é uma propriedade a qual invariavelmente é verdadeira durante toda a execução de um *loop*, de tal forma que a corretude deste pode ser demonstrada se a invariante se mantêm verdadeira
- antes da iteração inicial ($i = 0$),
- para cada iteração subsequente (se verdadeira em $i = k$, também o é para $i = k + 1$)
- e ao término do *loop* ($i = n$, onde $n$ é o valor de parada)
Para o algoritmo acima, seja $N \in \N$, temos como invariantes que $n \le N$ e $i = \log_2n$.
**Prova**
Para $n$ temos:
- **Inicialização:** Para $N = 1$, $n_0 = 1$, então $n_0 \le N$.
- **Manutenção:** Para $N = k$ na iteração $x$, $x > 0$, assumimos $n_x \le k/2$. Ai para iteração $x + 1$ temos que o valor de $n_{x + 1} = 2n_x$. Como $n_x \le k/2$, tem-se que $n_{x + 1} \le k$, ou seja, $n_{x + 1} \le N$.
- **Término:** Para se encerrar na iteração $x$ tem-se que $n_x > N/2$ seja porque $n = N = 1$ ou, senão, porque $n_x > N \div 2$ quando $n_{x - 1} \le N/2$. No primeiro caso nada resta a demonstrar, mas no segundo caso segue que $n_x = 2n_{x - 1}$, então
$$
n_{x - 1} \le N/2 \stackrel{\times 2}{\implies} 2n_{x - 1} \le N \implies n_x \le N
$$
Para $i$ temos:
- **Inicialização:** Para $N = 1$, $n_0 = 1$ e $i_0 = 0$, então $i_0 = \log_2 n_0$.
- **Manutenção:** Para $N = k$ na iteração $x$ assumimos que $n_x \le k/2$ e $i_x = \log n_x$, para a iteração $x + 1$ temos que o valor de $n_{x+1} = 2n_x$ e $i_{x+ 1} = i_x + 1$. Logo,
$$
\log_2n_{x + 1} = \log_22n_x = \log_2n_x + \log_22
= i_x + 1 = i_{x + 1}
$$
- **Término:** Para se encerrar na iteração $x$ tem-se que $n_x > N/2$ seja porque $n = N = 1$ ou, senão, porque $n_x > N \div 2$ quando $n_{x - 1} \le N/2$. No primeiro caso $i = 0$ nada resta a demonstrar, mas no segundo caso segue que $n_x = 2n_{x - 1}$ e $i_{x - 1} = \log_2n_{x - 1}$, então
$$
\log_2n_x = \log_22n_{x - 1} = \log_2n_{x - 1} + \log_22
= i_{x - 1} + 1 = i_x
$$
**2.** Invariantes: $1 \le n \le N$ e $i \le \log_2N$. A demonstração é análoga a anterior. Pode ser feita aqui subsequentemente havendo tempo.
**3.** Vide `lg.c`
**4.** O que faz a função abaixo? Escreva o invariante que explica a função.
```c
int tlg (int N) {
int i = 0, n = 1;
while (n < N) {
n *= 2;
i += 1;
}
return i;
}
```
Essa é a função que apresenta o resultado de $\lceil \log_2N \rceil$. Os invariantes são $n < 2N$ e $i = \log_2 n$.
**5.** O que é o *teto* de um número real $r$?  Se $R$ é um número estritamente positivo, qual a relação entre o teto de  $log_{10} R$  e  $R$?  Escreva uma função recursiva que receba um número inteiro estritamente positivo $N$ e devolva o teto de $log_{10} N$.
O menor número inteiro $i$ tal que $i \ge r$. O teto do $\log_{10}R$ fornece o número de dígitos necessários a representar a parte inteira de $R$ em números decimais. Vide `lg.c`.
## Exercícios 3
1. Sim.
2. Vide `overflow.c`
3.