95 lines
3.2 KiB
Markdown
95 lines
3.2 KiB
Markdown
# 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.
|
||
|
||
|