A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Adição e subtração Capítulo 4: Jean Pierre Descamps; Géry Jean Antoine Bioul; Gustavo D.Sutter Synthesis of Arithmetic Circuits – New Jersey, John Wiley.

Apresentações semelhantes


Apresentação em tema: "Adição e subtração Capítulo 4: Jean Pierre Descamps; Géry Jean Antoine Bioul; Gustavo D.Sutter Synthesis of Arithmetic Circuits – New Jersey, John Wiley."— Transcrição da apresentação:

1 Adição e subtração Capítulo 4: Jean Pierre Descamps; Géry Jean Antoine Bioul; Gustavo D.Sutter Synthesis of Arithmetic Circuits – New Jersey, John Wiley & Sons, 2006.

2 Introdução Adição é usada como uma operação primitiva para computar as maioria das funções aritméticas. Para minimizar o tempo de computação várias idéias tem sido propostas. –Uma delas consiste em modificar o algoritmo clássico tal que o tempo de computação de cada vai-um seja mínimo; a complexidade no tempo ainda é proporcional a n, mas essa constante de proporcionalidade é menor. –Uma outra abordagem baseia-se em diferentes sistemas de numeração; em vez de adicionar dois números de n dígitos na base B, dois números na base B s de n/s dígitos são considerados. –Vários algoritmos, diferentes dos clássicos e geralmente baseados em alguma estrutura em árvore, tem sido propostos. Se o paralelismo implícito for considerado, atinge-se um tempo de execução proporcional a log n.

3 Adição de números naturais Algoritmo básico. Considerar as representações base B de dois números de n dígitos: O seguinte algoritmo computa a representação de z = z + y + c in de n+1 dígitos. Algoritmo 4.1: q(0) := c_in; for i in 0..n-1 loop if x(i) + y(i) + q(i) > B-1 then q(i+1) := 1; else q(i+1) := 0; end if; z(i) := (x(i) + y(i) + q(i)) mod B; end loop; z(n) := q(n);

4 Como q(i+1) é uma função de q(i) o tempo de execução do algoritmo anterior é proporcional a n. Modificação do algoritmo para reduzir o tempo de execução: - definir duas funções binárias de duas variáveis, a saber, funções de propagação (p) e geração (g): p(a,b) = 1 se a + b = B-1, p(a,b) = 0 caso contrário; g(a,b) = 1 se a + b > B-1, g(a,b) = 0 caso contrário. - o vai-um q i+1 pode ser calculado assim: if p( x(i), y(i) ) = 1 then q(i+1) := q(i); else q(i+1) := g( x(i),y(i) ); end if;

5 Algoritmo com geração e propagação de vai-um Algoritmo 4.2: -- computação das condições de geração e propagação: for i in 0..n-1 loop g(i):= g(x(i),y(i));p(i) := p(x(i),y(i)); end loop; -- computação do vai-um: q(0) := c_in; for i in 0..n-1 loop if p(i)=1 then q(i+1):= q(i); else q(i+1):= g(i); end if; end loop; -- computação das soma: for i in 0..n-1 loop z(i):= (x(i)+y(i)+q(i)) mod B; end loop; z(n):= q(n);

6 Algoritmo mais rápido Ou seja, os valores de q(1), q(2),...,q(n) podem ser calculados em paralelo: -- computação do vai-um: q(0) := c_in; for i in 0..n-1 loop if p(i)=1 then q(i+1):= q(i); else q(i+1):= g(i); end if; end loop; Exemplo: q(0) = c_in q(1) = g(0)v p(0).q(0) q(2) = g(1)v p(1).q(1) q(2) = g(1) v g(0).p(1) v q(0).p(0).p(1).... q(i) = g(i-1)v p(i-1).q(i-1) v = or. = and

7 Algoritmo mais rápido (cont.) Algoritmo 4.3: --computação das condições de geração e propagação: for i in 0..n-1 loop g(i):= g(x(i).y(i)); p(i):= p(x(i).y(i)); end loop; -- computação do vai-um: q(0) := c_in; for i in 1..n loop q(i):= g(i-1) or g(i-2)*p(i-1) or... or g(0)*p(1)*...* p(i-1) or q(0) * p(0) * p(1)*... * p(i-1); end loop; -- computação da soma for i in 0..n-1 loop z(i) := (x(i) + y(i) + q(i)) mod B; end loop; z(n) := q(n);

8 O algoritmo 4.3 consiste de 3 iterações cujas operações podem ser executadas em paralelo, pois q(i) depende apenas de x, y e c_in, mas não de vai-um anteriores. Não obstante, a execução de q(i):= g(i-1) or g(i-2)*p(i-1) or... or g(0)*p(1)*...* p(i-1) or q(0) * p(0) * p(1)*... * p(i-1); implica na computação de uma função de (2.i+1) variáveis. Para simplificação, dois novos conceitos são introduzidos: dot operation e funções de geração e propagação generalizadas. Dados 2 vetores binários e 2 elementos a i =(a i 0, a i 1 ) e a k = (a k0, a k1 ) um dot operation define uma função de em : Exemplo:

9 Dadas as funções de geração e de propagação g(i) e p(i), para as funções de geração e propagação generalizadas g(i:i-k) e p(i:i-k), para e são assim definidas: Baseado no cálculo paralelo de q(i) e nas funções generalizadas temos: q(i+1) = g(i:i-k)V p(i:i-k).q(i-k). Funções de geração e propagação generalizadas.

10 Algoritmo com funções de geração e propagação generalizadas Algoritmo 4.4: -- computação das condições de geração de propagação: for i in 0..n-1 loop g(i) := g(x(i),y(i)); p(i):= p(x(i),y(i)); end loop; -- computação das condições de geração e propagação generalizadas: for i in 1..n loop (g(i-1):0),p(i-1):0)):= (g(i-1),p(i-1)) dot (g(i-2),p(i-2)) dot... dot (g(0),p(0)); end loop; -- computação do vai-um: q(0) := c_in; for i in 1..n loop q(i) := g(i-1:0) or p(i-1:0)* q(0); end loop; -- computação da soma: for i in 0..n-1 loop z(i) := (x(i)+y(i)+q(i)) mod B; end loop; z(n) := q(n);

11 A segunda iteração do algoritmo anterior pode ser realizada de várias formas. Dado um conjunto de dados de entrada a(0), a(1),..., a(n-1) e um operador associativo (dot), computar Um algoritmo simples seria b(0) := a(0); for i in 1..n-1 loop b(i):= a(i) dot b(i-1); end loop. Não obstante, muitos algoritmos melhores tem sido propostos, dentre os quais dois serão descritos a seguir. -- computação das condições de geração e propagação generalizadas: for i in 1..n loop (g(i-1):0),p(i-1):0)):= (g(i-1),p(i-1)) dot (g(i-2),p(i-2)) dot... dot (g(0),p(0)); end loop;

12 Na definição de dot_procedure, os parâmetros são um número natural n ( o número de dados de entrada) e dois vetores de n componentes (os dados de entrada e saída). Procedure dot_procedure (n: in natural; a: in data_vector (0..n-1); b: out data_vector (0..n-1)); Assume-se que n é uma potência de 2 (se necessário, devem ser adicionados 0s). O primeiro algoritmo consiste em: a) computar b) chamar o dot_procedure com parâmetros n/2, c e d, tais que c) computar os componentes que faltam de b:

13 O esquema de computação para n = 16

14 Algoritmo Dot Procedure (1) Procedure dot_procedure (n: in natural; a: in data_vector(0..n-1); b: out data_vector(0..n-1)) is c,d: data_vector(0..(n/2)-1); begin if n = 2 then b(0) := a(0); b(1) := a(1) dot a(0); else for i in 0..(n/2)-1 loop c(i):= a((2*i)+1 dot a(2*i); end loop; dot_procedure (n/2, c, d); b(0) := a(0); for i in 1..(n/2)-1 loop b(2*i) := a(2*i) dot d(i-1); b((2*i) + 1) := d(i); end loop; end if; end dot_procedure; Algoritmo 4.5:

15 Tempo de execução Ambos os loops for são de dot operations que podem ser executados em paralelo. O tempo de execução total T(n) é igual a T dot + T(n/2) + T dot, com T(2) = T dot, tal que T(n) = (2.(log 2 n)-1).T dot. n=16 n=8 n=4 n=2 Tdot T(n/2) Tdot Temos log 2 n iterações, cada qual com 2.Tdot, com exceção da última que tem apenas um Tdot, portanto: T(n) = (2.(log 2 n)-1).T dot.

16 Segundo algoritmo O segundo algoritmo consiste em: a) chamar dot_procedure com parâmetros n/2, a(0..(n/2)-1), e b(0..(n/2)-1); b) chamar dot_procedure com parâmetros n/2, a((n/2)..n-1), e c, tal que c) computar os componentes que faltam de b,

17 Esquema de computação para n = 16

18 Algoritmo Dot Procedure (2) Procedure dot_procedure (n: in natural; a: in data_vector(0..n-1); b: out data_vector(0..n-1)) is c: data_vector(0..(n/2)-1); begin if n = 2 then b(0) := a(0); b(1) := a(1) dot a(0); else dot_procedure (n/2, a(0..(n/2)-1), b(0..(n/2)-1); dot_procedure (n/2, a((n/2)-1)..n-1), c); for i in 1..(n/2)-1 loop b(i+n/2)) := c(i) dot b((n/2)-1); end loop; end if; end dot_procedure; Ambas as chamadas de procedimentos podem ser executadas em paralelo e os loops for são de dot operations que podem ser executadas em paralelo. O tempo de execução total T(n) é igual a T(n/2)+T dot, com T(2) = T dot, tal que T(n) = (log 2 n).T dot. Algoritmo 4.6:

19 Parallel-Prefix Addition a, b: data_vector (0..n-1, 0..1); begin -- computação de condições de geração e propagação for i in 0..n-1 loop a(i,0) := g(x(i), y(i)); a(i,1):= p(x(i), y(i))); end loop; -- computação de condições de geração e propagação generalizadas dot_procedure (n, a, b); -- computação de vai-um q(0) := c_in; for i in 1..n loop q(i) := b(i,0) or b(i,1)* q(0); end loop; -- computação de soma for i in 0..n-1 loop z(i) := (x(i) +y(i) + q(i) ) mod B; end loop; z(n) := q(n); Algoritmo 4.7

20 O algoritmo precedente é constituído de 3 iterações, cujas operações podem ser executadas em paralelo, e uma chamada para o dot_procedure cujo tempo de execução é proporcional a log(n). Assim, para valores grandes de n, o tempo de execução do algoritmo é praticamente proporcional a log(n). O tempo de execução logaritmico pode ser obtido por diferentes algoritmos usando dois novos procedimentos (carry_lookahead_procedure e carry_procedure).

21 Carry_lookahead_procedure (preliminares) procedure carry_lookahead_procedure (n: in natural; a: in data_vector (0..n-1, 0..1); c_in: in bit; q: out bit_vector (1..n)); computa os n vai-ums q(1), q(2),..., q(n), em função de n condições de geração e propagação g(t) = a(t,0) e p(t) = a(t,1), e de c_in,

22 Carry_procedure (preliminares) procedure carry_procedure (n: in natural; b: in data_vector (0..n-1, 0..1); c_in: in bit; q: out bit_vector (1..n)); Computa os n vai-ums q(1), q(2),..., q(n), em função de n condições de geração e propagação generalizadas g(t:0) = b(t,0), p(t:0) = b(t,1) e de c_in:

23 Carry_lookahead_procedure Assume que n pode ser fatorado sob a forma n = k.s. O algoritmo consiste em: chamar k vezes o dot_procedure com parâmetros s, a(j.s.. j.s + s-1) e c(j, 0..s-1), onde tal que

24 Carry-lookahead-procedure(cont.) Chamar o carry_lookahead_procedure com parâmetros k, c(0..k-1,s-1), c_in e d, tal que Chamar k vezes o carry_procedure com parâmetros s-1, c(j, 0..s-2), d(j) e e(j, 0..s-2), onde tal que c_in

25 carry_lookahead_procedure de 16 entradas

26 procedure carry_look_ahead_procedure (n: in natural; a: in data_vector (0..n-1, 0..1); c_in: in bit; q: out bit_vector (1..n)) is c: data_vector (0..k-1, 0..s-1, 0..1); d bit_vector (0..k-1); begin for j in 0..k-1 loop dot_procedure (s, a(j*s..j*s+s-1), c(j, 0..s-1)); end loop; carry_lookahead_procedure (k, c(0..k-1, s-1), c_in, d); for j in 0..k-1 loop carry_procedure (s-1, c(j, 0..s-2), d(j), e(j, 0..s-2)); end loop; for j in 1..k-1 loop q(j*s) := d(j); end loop; for j in 0..k-1 loop for i in 0..s-2 loop q(j*s+i+1) := e(j,i); end loop; end loop; end carry_lookahead_procedure; Algoritmo 4.8

27 Carry_procedure O carry_procedure computa: (equação 4.10) Procedure carry_procedure (n: in natural; b: in data_vector (0..n-1, 0..1); c_in : in bit; q: out bit_vector (1..n)) is begin for t in 1..n loop q(t)= b(t-1,0) v c_in.b(t-1,1); end loop; end carry_procedure;

28 Tempo de execução Seja T(n) o tempo de execução de carry_lookahead_procedure, T 1 (n) o tempo de execução de dot_procedure, e T 2 o tempo de execução de qualquer equação 4.10 do carry_procedure. As k chamadas ao dot_procedure podem ser executadas em paralelo, e o mesmo ocorre com as k chamadas para carry_procedure. Além disso, dentro do carry_procedure a equação 4.10 pode ser calculada em paralelo. Assim, Assume-se que n = s 1.s s m. O algoritmo obtido pelas chamadas recursivas de carry_lookahead_procedure tem um tempo de computação que pode ser calculado como segue: Tal que Em particular, se n = s m,

29 Carry_lookahead_addition a: data_vector (0..n-1, 0..1); begin -- computação de condições de geração e propagação for i in 0..n-1 loop a(i,0) := g(x(i), y(i)); a(i,1):=p(x(i), y(i)); end loop; -- computação de vai-um carry_lookahead_procedure (n, a, c_in, q); q(0) := c_in; -- computação de soma for i in 0..n-1 loop z(i) := (x(i)+y(i)+q(i)) mod B; end loop; z(n): q(n); end; Algoritmo 4.9

30 Adição de operandos longos No caso de adições com operandos longos, é necessário quebrar os operandos de n dígitos em fatias de s dígitos. Um exemplo típico é a implementação de operações aritméticas de n bits em microprocessadores de m bits, com m

31 Adição de operandos longos Então, o seguinte algoritmo computa x + y + c in. Algoritmo 4.10 q:= c_in; for i in 0..n/s-1 loop natural_addition (s, q, x(i*s..(i*s)+s-1), y( i*s..(i*s) + s-1), q, z(i*s..(i*s)+s-1)); end loop; z(n) := q; n = 16, s = 4 x( ) = x (0..3) x( ) = x (4..7)..... x( ) = x (12..15) y (0..3) y (4..7)..... y (12..15) z (0..3) z (4..7)..... z (12..15) i=0 i=1... i=n/s-1=16/4-1=3

32 Dependendo do procedimento natural_addition, o tempo de execução é proporcional a (n/s).s = n ou (n/s).log s. Observa-se que versões modificadas de outros algoritmos não diminui esse tempo - todos eles incluem n comandos: z(i) := (x(i) + y(i) + q(i)) mod B; equivalente, em base B s a n/s comandos natural_addition (s, q(i), x(i*s..(i*s)+s-1), y (i*s..(i*s)+ s-1), not_used, z(i*s..(i*s)+s-1)); Como os n/s comandos devem ser executados sequencialmente (restrição de operandos longos), o tempo de execução deve ser proporcional a (n/s).s = n ou (n/s).log(s). Tempo de execução

33 Adição multioperando Uma outra operação importante é a adição multioperando, que é a computação de onde todo é um número natural. Assumir que a soma total não exceda n dígitos e que todos os operandos são expressos em n dígitos. O seguinte algoritmo computa z. Algoritmo: adição básica multioperando Algoritmo 4.11 accumulator:= 0; for j in 0..m-1 loop natural_addition (n, 0, accumulator, x(j), not_used, accumulator); end loop; z := accumulator; O tempo de execução é proporcional a m.n ou m.log n dependendo do procedimento de natural_addition selecionado.

34 Um conceito interessante para execução de adições multioperando é o stored- carry encoding do resultado de uma adição de 3 operandos. Assumir que um procedimento procedure three-to-two (w, x, y: in natural; u, v: out natural); seja definido, e que compute u e v tais que w + x + y = u + v. Então o seguinte algoritmo computa a soma de m números naturais. Algoritmo 4.12 : three-to-two (x(0), x(1),x(2), u(0), v(0))); for j in 3..m-1 loop three-to-two (x(j), u(j-3), v(j-3), u(j-2), v(j-2)); end loop; natural_addition (n, 0, u(m-3), v(m-3), not_used, z); Algoritmo three-to-two

35 stored-carry_encoding O procedimento three-to-two consiste em expressar a soma z de três números naturais (w, x, y) em forma de par (u, v) de dois números naturais de tal forma que z = u + v. Assumir que w, x, e y são números de n dígitos, e q_in seja um número de 1 dígito. O seguinte algoritmo computa dois números de n dígitos u e v e um número de 1 dígito q_out, tais que w + x+ y + q_in = q_out.B n + u + v. Algoritmo 4.13 : stored-carry encoding procedure stored-carry_encoding (w, x, y: in digit_vector (0..n-1); q_in: in digit; u, v: out digit_vector (0..n-1); q_out: out digit) is begin q(0) := q_in; for i in 0..n-1 loop q(i+1) := (w (i) + x(i) + y(i))/B; u(i) := (w(i) + x(i) + y(i)) mod B; end loop; v:= q(0..n-1); q_out:= q(n); end stored-carry_encoding

36 O algoritmo stored-carry_encoding é similar ao algoritmo básico de adição. Dois dígitos são computados a cada passo, e o primeiro, q(i+1), pode ser considerado como um carry na base B. Não obstante, q(i+1) não depende de q(i) tal que n passos de iteração possam ser executados em paralelo. Em outras palavras, a cada passo o carry q(i+1) é guardado ao invés de ser transferido para a próxima iteração. Por essa razão, o par (u, v) é dito ser da forma stored-carry de z. O seguinte algoritmo multioperando, onde x(j,i) significa x (j) (i), é deduzido dos dois algoritmos anteriores (assumindo que z seja um número de n dígitos e que todos os operandos sejam expressos em n dígitos).

37 Carry-save addition Algoritmo 4.14 – carry-save addition stored-carry_encoding (x (0, 0..n-1), x(1, 0..n-1), x(2, 0..n-1), 0, u(0, 0..n-1), v(0, 0..n-1), not_used); for j in 3..m-1 loop stored-carry_encoding (x(j, 0..n-1), u(j-3, 0..n-1), v(j-3, 0..n-1), 0, u(j-2, 0..n-1), v(j-2, 0..n-1), not_used); end loop; z(0):= u(m-3, 0); natural_addition (n-1, 0, u(m-3, 1..n-1), v(m-3, 1..n-1), not_used, z(1..n-1)); O algoritmo acima é constituído de m-2 chamadas a stored-carry_encoding e uma chamada ao procedimento de adição de (n-1) dígitos, tal que o tempo de execução seja aproximadamente proporcional a m+n ou m+ log(n).

38 Adição longa multioperando Uma adição longa multioperando pode ser executada combinando os algoritmos 4.10 e Algoritmo 4.15 accumulator := 0; for j in 0..m-1 loop q:= 0; for i in 0..n/s -1 loop natural_addition(s, q, accumulator (i*s..(i*s)+s-1), x(j,i*s.. (i*s)+s-1), q, accumulator (i*s.. (i*s) + s-1)); end loop; z:= accumulator; O tempo de execução é proporcional a m.(n/s).s=m.n ou m.(n/s).log(s). O stored-carry_encoding pode também ser usado. A redução de m operandos de n dígitos para 2 operandos de n dígitos pode ser realizada, quebrando cada operando de n dígitos em n/s operandos de s-dígitos e chamando o procedimento stored-carry_encoding (m-2).(n/s) vezes. Então, os operandos assim obtidos são somados.

39 Algoritmo 4.16 – carry-save long-multioperand addition -- m-to-2 reduction q:= 0; for i in 0.. n/s -1 loop stored-carry_encoding (x(0, i*s.. (i*s)+s -1), x(1, i*s.. (i*s) + s-1), x(2, i*s..(i*s) + s-1), q, u(i*s.. (i*s) + s-1), v(i*s.. (i*s) + s-1), q); end loop; for j in 3..m-1 loop q := 0; for i in 0..n/s-1 loop stored-carry_encoding (x(j, i*s..(i*s)+s-1), u(i*s..(i*s)+s-1), v(i*s..(i*s)+s-1), q, u(i*s..(i*s)+s- 1), v(i*s..(i*s)+ s-1), q); end loop; -- 2-operand addition; q:= 0; for i in 0..n/s-1 loop natural_addition (s, q, u(i*s..(i*s)+s-1), v(i*s..(i*s)+s-1), q, z(i*s.. (i*s)+s-1); end loop; A redução m-to-2 é realizada em (m-2).(n/s) passos e o tempo de execução de adição de 2 operandos é proporcional a (n/s).s = n ou (n/s).log s. O tempo de execução total é aproximadamente proporcional a (n/s).(m+s) ou (n/s).( m + log s) ao invés de (n/s).m.s ou (n/s).m.log.s.

40 Subtração de números naturais O seguinte algoritmo computa representação de n dígitos de z = x – y – b in onde b in é o empresta um inicial, igual a 0 ou 1. Se z é negativo, ou seja, z não é um número natural, o empresta um q(n) de saída é igual a 1. Algoritmo 4.17 q(0) := b_in; for i in 0..n-1 loop if x(i) – y(i) – q(i) < 0 then q (i+1) := 1; else q(i+1) := 0; end if; r(i) := (x(i) – y(i) –q(i)) mod B; end loop; negative:= q(n);

41 Subtração de inteiros No caso de inteiros, os algoritmos de adição e subtração dependem da particular representação. Adição complemento de B: Dados dois inteiros x e y, em complemento de B de n dígitos, e um carry c in inicial igual a 0 ou 1, então z = x + y + c in é um inteiro em complemento de B de n+1 dígitos. Então os números naturais associados a x, y e z são R(x) = x mod B n+1, R(y) = y mod B n+1, R(z) = z mod B n+1, tais que Assim, o algoritmo de adição consiste em representar x e y com n+1 dígitos e somar os números naturais correspondentes, bem como o carry inicial, módulo B n+1 (isto é, sem levar em conta o carry de saída).

42 Algoritmo 4.18 – Adição complemento de B if x(n-1) < B/2 then x(n) := 0; else x(n) := B-1; end if; if y(n-1) < B/2 then y(n) := 0; else y(n) := B-1; end if; natural_addition (n+1, c_in, x, y, not_used, z); Exemplo: assumir que B = 10, n = 4, cin = 0, x = -2345, e y = Ambos x e y são negativos tal que eles sejam representados por R(x) = = 7655 e R(y) = = Primeiro representamos x e y com 5 dígitos: R(x)= e R(y) = Então somamos R(x) e R(y) módulo 10 5 : mod10 5 = Como o inteiro representado é negativo e igual a – 10 5 = -6019, que é a soma de x e y.

43 Mudança de sinal em complemento de B (negação) Dado um inteiro x em complemento de B de n dígitos, o negativo z = - x é um inteiro em complemento de B de n+1 dígitos (na realidade, o único caso em que o número –x não pode ser representado em n dígitos é quando x = -B n /2 e –x = B n /2; isto é, -x = 0.B n + (B/2).B n B n B 0 ). A computação da representação de –x é baseada na seguinte propriedade: Propriedade 4.3: dados dois números naturais na base B de m dígitos, então,

44 Algoritmo 4.19 – mudança de sinal em complemento de B if x (n-1) < B/2 then x(n) := 0; else x(n) := B-1; end if; for i in 0..n loop x(i) := B-1-x(i); end loop; natural_addition (n+1, 1, x, 0, not_used, z); Exemplo 1: Assumir que B = 10, n = 4, x = 2345; x é positivo e representado por R(x) = x = Primeiro, representar x com 5 dígitos: R(x)= Então complementar todos os dígitos de B -1 = 9, e adicionar 1: ( ) mod 10 5 = O inteiro representado por é – 10 5 =

45 exemplos Exemplo 2: Se x = então a representação em 4 dígitos e x é 5000 e a de 5 dígitos é Complementando todos os dígitos e adicionando 1, o resultado obtido é ( ) módulo 10 5 = 05000, que é a representação do número positivo de Exemplo 3: Se x = 0 então a representação em 4 dígitos de x é 0000 e de 5 dígitos, Complementando todos os dígitos e adicionando 1 o resultado obtido é ( ) mod 10 5 = 00000, que é a representação positiva de 0.

46 Subtração complemento de B Dados dois inteiros x e y de n dígitos e complemento de B, e um borrow b in igual a 0 ou 1, então z = x – y – b in é um inteiro em complemento de B de n+1 dígitos. Assumir que x e y são representados em n + 1 dígitos. Então os números naturais associados a x, -y e z são R(x) = x mod B n+1, R(-y) = (y+1) mod B n+1 e R(z) = z mod B n+1, tais que Assim o algoritmo consiste em representar x e y com n+1 dígitos, complementar os dígitos de y e somar os números naturais correspondentes e o borrow de entrada invertido, em módulo B n+1. Algoritmo subtração em complemento de B if x(n-1) < B/2 then x(n) := 0; else x(n) := B-1; end if; if y(n-1) < B/2 then y(n) := 0; else y(n) := B-1; end if; for i in 0..n loop y(i) := B-1-y(i); end loop; c_in := 1- b_in; natural_addition (n+1, x, y, c_in, z, not_used);

47 exemplo Assumir que B = 10, n = 4, b in = 1, x = -2345, e y = x é negativo e y positivo, tais que sejam representados por R(x) = = 7655 e R(y) = y = Primeiro representar x e y com 5 dígitos: R(x) = e R(y) = Então, computar y = 96325, c in = 1 – b in = 0 e (R(x) + y + c in ) mod 10 5 = ( ) mod 10 5 = O inteiro representado por é igual a – 10 5 = -6020, isto é, –

48 Detecção de overflow em complemento de B Em certos casos é necessário saber se o resultado é realmente um número de n+1 dígitos e não um número de n dígitos. Um caso típico é uma unidade aritmética de um computador de uso geral: ambos os operandos e o resultado são números de n bits, e um flag de overflow é acionado se o resultado não se enquadra em n bits. Assumir que os algoritmos anteriores (adição, inversão e subtração) são executados sem estender os operandos para n+1 bits: 1. considerar o caso da adição. Um overflow pode ocorrer quando ambos os operandos tem o mesmo sinal. Primeiro observar que se x e y estão no intervalo então isto é

49 Ou seja, se x e y são positivos, a soma x + y + cin pode ser maior ou igual a B n /2. Se R(x) = x e R(y) = y, então, R(z) = (x + y+ c in ) mod B n, e de acordo com a hipótese anterior isto é tal que A conclusão é que a soma de dois números positivos, mais um carry inicial, gera um número aparentemente negativo se somente n dígitos são disponíveis

50 Se x e y são negativos, a soma x +y + c in pode ser menor que –B n /2. Se R(x) = B n + x e R(y) = B n + y, então R(z) = (2.B n + x + y + c in ) mod B n, e de acordo com a hipótese anterior isto é, tal que A conclusão é que a soma de dois números negativos, mais um carry inicial, gera um número aparentemente positivo se somente n dígitos são disponíveis

51 Resumindo, a detecção de overflow é obtida observando o dígito de sinal dos operandos e do resultado. Sob forma booleana:

52 2. Já foi observado que quando se nega um número (mudança de sinal) a única situação de overflow é quando x = -B n /2, a saber x(n-1)=B-1 e x(n- 2)=...=x(0)=0. O algoritmo de negação com n dígitos gera z = x. Novamente, basta observar os dígitos de sinal de ambos os operandos e o resultado: 3. Se uma subtração é realizada, um overflow pode ocorrer se um operando é negativo e outro é positivo. Nesse caso, a conclusão é que a diferença entre um número negativo e um positivo, menos um borrow inicial, gera um número aparentemente positivo se somente n dígitos são usados. Como nos casos anteriores a detecção de overflow é obtida observando os dígitos de sinal dos operandos e do resultado.

53 Exemplos 1. Assumir que c in = 0, x = 2345 e y = 4674, e que o valor de x + y + c in é computado. Então, R(x) = x = 2345 e R(y) = y = tais que (R(x) + R(y) + c in ) mod = 7019, isto é, representação do número negativo Assumir que c in = 0, x = e y = -2174, e que o valor x +y + c in é computado. Então, R(x) = – 4726 = 5274 e R(y) = – 2174 = 7826, tais que (R(x) + R(y) + c in ) mod = 3100, isto é, representação de um número positivo. 3. Computar a diferença entre x = 2345 e y = com b in = 0. As representações correspondentes são R(x)= 2345 e R(y) = – 4726 = 5274, tais que y= 4725 e ( ) mod = 7071, isto é, representação do número negativo

54 Sobre representação em complemento de B reduzido A extensão de sinal implica em duplicar o dígito de sinal. Se B =2 não existe diferença em relação à representação não-reduzida. Se x e y são números de n dígitos em complemento de B reduzido, então tal que e Se B>2 e B é par, tal que então e Assim ambos x + y + c in e x – y- b in são números em complemento de B de n dígitos. Existe overflow se o resultado não for um número na representação de complemento de B reduzido, isto é, o dígito de sinal não pertence a {0, B-1}. No caso de overflow negativo, o dígito negativo é igual a B-2 e 1 no caso de overflow positivo.

55 Exemplos Exemplo (B = 10, n =3, forma em complemento de 10 reduzido) 1. Assumir que c in = 0, x = 74, e y = 41, e que o valor de x+y é computado. Então R(x) = x = 074 e R(y) = y = 041, tais que (R(x)+R(y)+c in ) mod 1000 = 115, um número cujo dígito de sinal não pertence a {0,9}. 2. Assumir que c in = 0, x = -74, e y = -41, e que o valor x + y é computado. Então, R(x) = = 926 e R(y)= 1000 – 41 = 959, tais que (R(x) + R(y) + c in ) mod 1000 = 885, um número cujo sinal não pertence a {0,9}. A representação real é a forma não-reduzida de = Computar a diferença entre x = 74 e y = -41, com b in = 0. As representações são R(x) = x = 074 e R(y) = 1000 – 41 = 959, tal que y = 040 e ( ) mod 1000 = 115, um número cujo sinal não pertence a {0,9}, representando na realidade o número 115 na forma não-reduzida.

56 Excesso de E Propriedades: Dados dois inteiros x e y em excesso de E, um carry c in binário e um borrow b in, então Se x e y são dois números inteiros de n dígitos em excesso de E, e se z = x + y + c in é também um inteiro de n dígitos excesso de E, então o algoritmo direto consiste em representar x e y com n+1 dígitos, somá-los com c in e subtrair E. O resultado R(z) é um número natural de n+1 dígitos cujo primeiro dígito é 0. Assumir que o procedimento natural_subtraction seja definido: procedure natural_subtraction (s: in natural; borrow: in bit; x, y: in digit_vector(0..s-1); next_borrow: out bit; z: out digit_vector(0..s-1));

57 Os seguintes algoritmos computam z = z + y + c in e z = x – y - b in. Algoritmo 4.22 Adição excesso de E x(n) := 0; y(n) := 0; natural_addition (n+1, x, y, c_in, w, not_used); natural_subtraction (n+1, w, E, 0, z, not_used); if z(n) > 0 then overflow:= true; end if; Algoritmo 4.23 subtração excesso de E x(n) := 0; y(n) := 0; natural_addition (n+1, x, E, 0, w, not_used); natural_subtraction (n+1, w, y, b_in, z, not_used); if z(n) > 0 then overflow:= true; end if;

58 Algoritmo mudança de sinal em excesso de E (negação) Algoritmo 4.24 Mudança de sinal em excesso de E x(n) := 0; E_by_2(0):= 0; for i in 1..n loop E_by_2(i) := E(i-1); end loop; natural_subtraction (n+1, E_by_2, x, 0, z, not_used); if z(n) > 0 then overflow:= true; end if;

59 Exemplos B = 0, n = 4, excesso de assumir que c in = 0, x = 2345 e y = 1674, e que o valor de x + y + c in é computado. Então, R(x) = e R(y) = 06674, tais que R(x) + R(y) + c in – = 09019, isto é, representação de assumir que c in = 0, x = e y = 1674, e que o valor de x + y + c in é computado. Então, R(x) = e R(y) = 06674, tais que R(x) + R(y) + c in – = 4329, isto é, representação de computar a soma de x = 2345 e y = 4726, com c in = 0. As representações correspondentes são R(x) = e R(y) = 09726, tais que R(x) + R(y) + c in – = 12071, resultando em overflow. 4. computar a diferença entre x = 2345 e y = 4726, com b in = 0. As representações correspondentes são R(x) = e R(y) = 09726, tais que R(x) - R(y) - b in = 2619, representando

60 Exemplos (cont.) 5. computar a diferença entre x = e y = 4726, com b in = 0. As representações correspondentes são R(x) = e R(y) = 09726, tais que R(x) - R(y) - b in = (módulo B n+1 = ), resultando em overflow. 6. computar o negativo de x = A correspondente representação é igual a R(x) = tal que –R(x) = 10000, que resulta em overflow.

61 Adição e subtração em sinal e magnitude Dados dois números inteiros x e y, então z = x + y + c in é um inteiro em sinal e magnitude de n+1 dígitos. O seguinte algoritmo computa z: Algoritmo 4.25 If sign (x) = sign(y) then a:= abs (x) + abs (y); else a:= abs(x) – abs(y); end if; if a < 0 then sign (z) := sign(y); abs(z) := -a ; else sign (z) := sign(x); abs(z) := a; end if;

62 Algoritmo alternativo sinal e magnitude Algoritmo 4.26 adição em sinal e magnitude abs_x := x (0..n-2) & 0; abs_y := y (0..n-2) & 0; if x(n-1) = y (n-1) then natural_addition (n, abs_x, abs_y, 0, a, not_used); else for i in 0..n-1 loop abs_y (i):= B-1-abs_y(i); end loop; natural_addition (n, abs_x, abs_y, 1, a, not_used); end if; if a(n-1) = B-1 then z(n) := y(n-1) ; for i in 0..n-1 loop a(i) := B-1-a(i); end loop; natural_addition (n, 0, a, 1, z(0..n-1), not_used); else z(n) := x (n-1); z( 0..n-1):= a; end if;

63 Exemplo (B=10, n=5). Assumir que x = e y = Primeiro expressar os valores absolutos com cinco dígitos: abs(x) = e abs(y) = Como os sinais são diferentes, computar = O primeiro dígito é igual a 9, indicando um valor negativo. O sinal do resultado é o mesmo do sinal de y e o valor absoluto é = 05329, tal que o resultado seja


Carregar ppt "Adição e subtração Capítulo 4: Jean Pierre Descamps; Géry Jean Antoine Bioul; Gustavo D.Sutter Synthesis of Arithmetic Circuits – New Jersey, John Wiley."

Apresentações semelhantes


Anúncios Google