Algoritmos de multiplicação

Um algoritmo de multiplicação é um algoritmo (ou método) para multiplicar dois números. Dependendo do tamanho dos números, diferentes algoritmos são mais eficientes do que outros. Inúmeros algoritmos são conhecidos e tem havido muita investigação sobre o tópico.

O método mais antigo e simples, conhecido desde a antiguidade como multiplicação longa ou multiplicação escolar, consiste em multiplicar cada dígito do primeiro número por cada dígito do segundo e somar os resultados. Este método tem uma complexidade de tempo de , onde é o número de dígitos. Quando feita à mão, esta operação também pode ser reformulada como o método da grelha ou a multiplicação em treliça. Em software, isto pode ser chamado de "deslocar e adicionar" (shift and add) devido aos deslocamentos de bits e à adição serem as duas únicas operações necessárias.

Em 1960, Anatoly Karatsuba descobriu a multiplicação de Karatsuba, desencadeando uma onda de investigação em algoritmos de multiplicação rápida. Este método usa três multiplicações em vez de quatro para multiplicar dois números de dois dígitos. (Uma variante disto também pode ser usada para multiplicar números complexos rapidamente.) Feito recursivamente, este método tem uma complexidade de tempo de . Dividir os números em mais de duas partes resulta na multiplicação de Toom-Cook; por exemplo, usar três partes resulta no algoritmo Toom-3. O uso de muitas partes pode definir o expoente arbitrariamente próximo de 1, mas o fator constante também cresce, tornando-o impraticável.

Em 1968, foi descoberto o algoritmo de Schönhage-Strassen, que faz uso de uma transformada de Fourier sobre um módulo. Este tem uma complexidade de tempo de . Em 2007, Martin Fürer propôs um algoritmo com complexidade . Em 2014, Harvey, Joris van der Hoeven e Lecerf propuseram um com complexidade , tornando assim explícita a constante implícita; isto foi melhorado para em 2018. Por fim, em 2019, Harvey e van der Hoeven apresentaram um algoritmo galáctico com complexidade . Isto corresponde a um palpite de Schönhage e Strassen de que este seria o limite ideal, embora isso ainda hoje permaneça como uma conjetura.

Os algoritmos de multiplicação de inteiros também podem ser usados para multiplicar polinómios por meio do método de substituição de Kronecker.

Multiplicação longa

Se for utilizado um sistema de numeração posicional, uma forma natural de multiplicar números é ensinada nas escolas como multiplicação longa, por vezes chamada de multiplicação escolar, ou ainda algoritmo padrão: multiplica-se o multiplicando por cada dígito do multiplicador e, em seguida, somam-se todos os resultados devidamente deslocados. Este processo requer a memorização da tabuada para dígitos únicos.

Este é o algoritmo habitual para multiplicar números maiores à mão na base 10. Uma pessoa que faça a multiplicação longa em papel irá escrever todos os produtos e, depois, somá-los; um utilizador de ábaco irá somar os produtos assim que cada um deles for calculado.

Exemplo

Este exemplo utiliza a multiplicação longa para multiplicar 23.958.233 (multiplicando) por 5.830 (multiplicador) e chega a 139.676.498.390 como resultado (produto).

      23958233
×         5830
———————————————
      00000000 ( =  23.958.233 ×     0)
     71874699  ( =  23.958.233 ×    30)
   191665864   ( =  23.958.233 ×   800)
+ 119791165    ( =  23.958.233 × 5.000)
———————————————
  139676498390 ( = 139.676.498.390)

Outras notações

Nalguns países, como a Alemanha, a multiplicação acima é descrita de forma semelhante, mas o produto original é mantido na horizontal e o cálculo começa com o primeiro dígito do multiplicador:[1]

23958233 · 5830
———————————————
   119791165
    191665864
      71874699
       00000000
———————————————
   139676498390

O pseudocódigo abaixo descreve o processo da multiplicação demonstrada acima. Mantém apenas uma linha para preservar a soma que, no final, se torna o resultado. Note que o operador '+=' é usado para denotar a soma ao valor existente e a operação de armazenamento (à semelhança de linguagens como Java e C) por uma questão de compactação.

multiply(a[1..p], b[1..q], base)                             // Operandos contendo os dígitos mais à direita no índice 1
  product = [1..p+q]                                         // Alocar espaço para o resultado
  for b_i = 1 to q                                           // para todos os dígitos em b
    carry = 0
    for a_i = 1 to p                                         // para todos os dígitos em a
      product[a_i + b_i - 1] += carry + a[a_i] * b[b_i]
      carry = product[a_i + b_i - 1] / base
      product[a_i + b_i - 1] = product[a_i + b_i - 1] mod base
    product[b_i + p] = carry                                 // o último dígito provém do transporte final (carry)
  return product

Utilização em computadores

Alguns chips implementam a multiplicação longa, em hardware ou em microcódigo, para vários tamanhos de palavras inteiras e de vírgula flutuante. Na aritmética de precisão arbitrária, é comum utilizar a multiplicação longa com a base definida para 2w, onde w é o número de bits numa palavra, para multiplicar números relativamente pequenos. Para multiplicar dois números com n dígitos utilizando este método, são necessárias cerca de n2 operações. Mais formalmente, multiplicar dois números de n dígitos utilizando a multiplicação longa requer operações de um único dígito (adições e multiplicações).

Quando implementados em software, os algoritmos de multiplicação longa têm de lidar com o overflow (transbordo) durante as adições, o que pode ser computacionalmente dispendioso. Uma solução típica é representar o número numa base pequena, b, de modo que, por exemplo, 8b seja um número inteiro de máquina representável. Desta forma, várias adições podem ser efetuadas antes de ocorrer um overflow. Quando o número se torna demasiado grande, adicionamos uma parte dele ao resultado, ou transportamos (carry) e mapeamos a parte restante de volta para um número inferior a b. Este processo é chamado de normalização. Richard Brent usou esta abordagem no seu pacote Fortran, MP.[2]

Os computadores usaram inicialmente um algoritmo muito semelhante à multiplicação longa na base 2, mas os processadores modernos têm circuitos otimizados para multiplicações rápidas usando algoritmos mais eficientes, ao custo de uma implementação de hardware mais complexa.[carece de fontes?] Na base dois, a multiplicação longa é por vezes chamada de "deslocar e adicionar" (shift and add), porque o algoritmo simplifica-se e consiste apenas em deslocar para a esquerda (multiplicar por potências de dois) e adicionar. A maioria dos microprocessadores atualmente disponíveis implementa este ou outros algoritmos semelhantes (como o algoritmo de Booth) para vários tamanhos de inteiros e de vírgula flutuante em multiplicadores de hardware ou em microcódigo.

Nos processadores atualmente disponíveis, uma instrução de deslocamento bit a bit (bit-wise shift) é geralmente (mas não sempre) mais rápida do que uma instrução de multiplicação e pode ser usada para multiplicar (deslocamento para a esquerda) e dividir (deslocamento para a direita) por potências de dois. A multiplicação por uma constante e a divisão por uma constante podem ser implementadas através de uma sequência de deslocamentos e adições ou subtrações. Por exemplo, existem várias maneiras de multiplicar por 10 usando apenas deslocamento de bits e adição.

 ((x << 2) + x) << 1 # Aqui 10*x é calculado como (x*2^2 + x)*2
 (x << 3) + (x << 1) # Aqui 10*x é calculado como x*2^3 + x*2

Nalguns casos, tais sequências de deslocamentos e adições ou subtrações terão um desempenho superior ao dos multiplicadores e, especialmente, aos dos divisores de hardware. Uma divisão por um número da forma ou pode, muitas vezes, ser convertida para uma dessas sequências curtas.

Algoritmos para multiplicação à mão

Para além da multiplicação longa padrão, existem vários outros métodos utilizados para efetuar multiplicações à mão. Estes algoritmos podem ser concebidos tendo em vista a rapidez, a facilidade de cálculo ou o seu valor educativo, em especial quando não se dispõe de computadores ou de tabuadas.

Método da grelha

O método da grelha (ou método da caixa) é um método introdutório para multiplicações de vários dígitos que é frequentemente ensinado a alunos no ensino primário ou na escola primária. Tem feito parte integrante do currículo nacional de matemática do ensino primário em Inglaterra e no País de Gales desde o final da década de 1990.[3]

Ambos os fatores são divididos ("particionados") nas suas partes de centenas, dezenas e unidades, e os produtos das partes são então calculados explicitamente numa etapa relativamente simples apenas de multiplicação, antes de estas contribuições serem totalizadas para dar a resposta final numa etapa de adição separada.

O cálculo de 34 × 13, por exemplo, poderia ser efetuado utilizando a grelha:

  300
   40
   90
 + 12
 ————
  442
× 30 4
10 300 40
3 90 12

seguido da adição para obter 442, seja numa única soma (ver à direita), ou formando os totais linha a linha


Esta abordagem de cálculo (embora não necessariamente com a disposição explícita da grelha) também é conhecida como o algoritmo dos produtos parciais. A sua essência é o cálculo das multiplicações simples separadamente, com toda a adição a ser deixada para a etapa final de agrupamento.

Em princípio, o método da grelha pode ser aplicado a fatores de qualquer tamanho, embora o número de subprodutos se torne muito extenso à medida que o número de dígitos aumenta. Não obstante, é visto como um método explicitamente útil para introduzir a ideia das multiplicações de múltiplos dígitos; e, numa era em que a maioria dos cálculos de multiplicação é feita com recurso a uma calculadora ou a uma folha de cálculo, poderá na prática ser o único algoritmo de multiplicação de que alguns alunos precisarão alguma vez.

Multiplicação em treliça

Em primeiro lugar, monte a grelha marcando as suas linhas e colunas com os números a multiplicar. Depois, preencha as caixas com os dígitos das dezenas nos triângulos superiores e os dígitos das unidades nos inferiores
Por fim, some ao longo dos caminhos diagonais e faça os transportes (carries) conforme necessário para obter a resposta

A multiplicação em treliça (lattice), ou em gelosia (sieve), é algoritmicamente equivalente à multiplicação longa. Requer a preparação de uma treliça (uma grelha desenhada em papel) que orienta o cálculo e separa todas as multiplicações das adições. Foi introduzida na Europa em 1202 no livro Liber Abaci de Fibonacci. Fibonacci descreveu a operação como sendo mental, usando as mãos direita e esquerda para carregar os cálculos intermédios. Matrakçı Nasuh apresentou 6 variantes diferentes deste método no seu livro do século XVI, Umdet-ul Hisab. Era amplamente utilizado nas escolas do Enderun por todo o Império Otomano.[4] Os Ossos de Napier, ou Barras de Napier, também usavam este método, tal como publicado por Napier em 1617, ano da sua morte.

Como demonstrado no exemplo, o multiplicando e o multiplicador são escritos por cima e à direita de uma treliça, ou gelosia. Encontra-se na "Aritmética" de Muhammad ibn Musa al-Khwarizmi, uma das fontes de Leonardo mencionadas por Sigler, autor de "Fibonacci's Liber Abaci", 2002.[carece de fontes?]

  • Durante a fase de multiplicação, a treliça é preenchida com produtos de dois dígitos dos dígitos correspondentes que rotulam cada linha e coluna: o dígito das dezenas vai para o canto superior esquerdo.
  • Durante a fase de adição, a treliça é somada nas diagonais.
  • Por fim, se for necessária uma fase de transporte (carry), a resposta, tal como apresentada ao longo dos lados esquerdo e inferior da treliça, é convertida para a forma normal transportando os dígitos das dezenas como na adição ou na multiplicação longa.

Exemplo

As imagens à direita mostram como calcular 345 × 12 usando a multiplicação em treliça. Como exemplo mais complicado, considere a imagem abaixo que apresenta o cálculo de 23.958.233 multiplicado por 5.830 (multiplicador); o resultado é 139.676.498.390. Repare que o número 23.958.233 está ao longo do topo da treliça e o 5.830 está ao longo do lado direito. Os produtos preenchem a treliça e a soma desses produtos (na diagonal) encontra-se ao longo dos lados esquerdo e inferior. Em seguida, essas somas são totalizadas conforme se mostra.

     2   3   9   5   8   2   3   3
   +---+---+---+---+---+---+---+---+-
   |1 /|1 /|4 /|2 /|4 /|1 /|1 /|1 /|
   | / | / | / | / | / | / | / | / | 5
 01|/ 0|/ 5|/ 5|/ 5|/ 0|/ 0|/ 5|/ 5|
   +---+---+---+---+---+---+---+---+-
   |1 /|2 /|7 /|4 /|6 /|1 /|2 /|2 /|
   | / | / | / | / | / | / | / | / | 8
 02|/ 6|/ 4|/ 2|/ 0|/ 4|/ 6|/ 4|/ 4|
   +---+---+---+---+---+---+---+---+-
   |0 /|0 /|2 /|1 /|2 /|0 /|0 /|0 /|
   | / | / | / | / | / | / | / | / | 3
 17|/ 6|/ 9|/ 7|/ 5|/ 4|/ 6|/ 9|/ 9|
   +---+---+---+---+---+---+---+---+-
   |0 /|0 /|0 /|0 /|0 /|0 /|0 /|0 /|
   | / | / | / | / | / | / | / | / | 0
 24|/ 0|/ 0|/ 0|/ 0|/ 0|/ 0|/ 0|/ 0|
   +---+---+---+---+---+---+---+---+-
     26  15  13  18  17  13  09  00
 01
 002
 0017
 00024
 000026
 0000015
 00000013
 000000018
 0000000017
 00000000013
 000000000009
 0000000000000
 —————————————
  139676498390
= 139.676.498.390

Multiplicação camponesa russa

O método binário também é conhecido como multiplicação camponesa (ou russa), pois tem sido muito utilizado por pessoas classificadas como camponesas que, desse modo, não memorizaram as tabuadas de multiplicação necessárias para a multiplicação longa.[5]Predefinição:Falhou a verificação O algoritmo já estava em uso no antigo Egipto.[6] As suas principais vantagens são poder ser ensinado rapidamente, não exigir qualquer memorização e poder ser executado utilizando fichas, tais como fichas de póquer, caso papel e lápis não estejam disponíveis. A desvantagem é exigir mais passos do que a multiplicação longa, o que o pode tornar pesado para números grandes.

Descrição

Num papel, escreva numa coluna os números que obtém quando divide repetidamente o multiplicador por dois (metade), ignorando o resto; na coluna ao lado, duplique sucessivamente o multiplicando. Risque todas as linhas em que o último dígito do primeiro número seja par e some os números restantes da segunda coluna para obter o produto final.

Exemplos

Este exemplo recorre à multiplicação camponesa para multiplicar 11 por 3, obtendo um resultado de 33.

Decimal:     Binário:
11   3       1011  11
5    6       101  110
2   12       10  1100
1   24       1  11000
    ——         ——————
    33         100001

Descrevendo os passos de forma explícita:

  • O 11 e o 3 são escritos no topo.
  • O 11 é reduzido a metade (5,5) e o 3 é duplicado (6). A parte fracionária é descartada (5,5 passa a 5).
  • O 5 é reduzido a metade (2,5) e o 6 é duplicado (12). A parte fracionária é descartada (2,5 passa a 2). O valor na coluna da esquerda (2) é par, pelo que o valor na coluna da direita (12) é descartado.
  • O 2 é reduzido a metade (1) e o 12 é duplicado (24).
  • Todos os valores não riscados são somados: 3 + 6 + 24 = 33.

O método funciona porque a multiplicação é distributiva, logo:

Um exemplo mais complexo, utilizando os valores dos exemplos anteriores (23.958.233 e 5.830):

Decimal:             Binário:
5830  23958233       1011011000110  1011011011001001011011001
2915  47916466       101101100011  10110110110010010110110010
1457  95832932       10110110001  101101101100100101101100100
728  191665864       1011011000  1011011011001001011011001000
364  383331728       101101100  10110110110010010110110010000
182  766663456       10110110  101101101100100101101100100000
91  1533326912       1011011  1011011011001001011011001000000
45  3066653824       101101  10110110110010010110110010000000
22  6133307648       10110  101101101100100101101100100000000
11 12266615296       1011  1011011011001001011011001000000000
5  24533230592       101  10110110110010010110110010000000000
2  49066461184       10  101101101100100101101100100000000000
1  98132922368       1  1011011011001001011011001000000000000
  ————————————          1022143253354344244353353243222210110 (antes do transporte)
  139676498390         10000010000101010111100011100111010110

Multiplicação de um quarto de quadrado

Esta fórmula pode, em alguns casos, ser usada para tornar as tarefas de multiplicação mais fáceis de completar:

No caso em que e são números inteiros, temos que uma vez que e são ambos pares ou ambos ímpares. Isto significa que e é suficiente (pré-)calcular a parte inteira dos quadrados divididos por 4, como no exemplo que se segue.

Exemplos

Abaixo encontra-se uma tabela de pesquisa de um quarto de quadrados com o resto descartado para os dígitos 0 a 18; esta tabela permite a multiplicação de números até .

0123456789101112131415161718
0012469121620253036424956647281

Se, por exemplo, quisesse multiplicar 9 por 3, observaria que a soma e a diferença são 12 e 6, respetivamente. A pesquisa de ambos esses valores na tabela produz 36 e 9, cuja diferença é 27, o qual é o produto de 9 e 3.

História da multiplicação de um quarto de quadrado

Nos tempos pré-históricos, a multiplicação de um quarto de quadrado envolvia a função de piso; que algumas fontes[7][8] atribuem à matemática babilónica (2000–1600 a.C.).

Antoine Voisin publicou uma tabela de quartos de quadrados de 1 a 1000 em 1817 como auxiliar de multiplicação. Uma tabela maior de quartos de quadrados de 1 a 100.000 foi publicada por Samuel Laundy em 1856,[9] e uma tabela de 1 a 200.000 por Joseph Blater em 1888.[10]

Os multiplicadores de um quarto de quadrado foram usados em computadores analógicos para formar um sinal analógico que fosse o produto de dois sinais de entrada analógicos. Nesta aplicação, a soma e a diferença de duas tensões de entrada são formadas usando amplificadores operacionais. O quadrado de cada um destes é aproximado usando circuitos de funções lineares por partes. Por fim, a diferença dos dois quadrados é formada e escalada por um fator de um quarto utilizando ainda outro amplificador operacional.

Em 1980, Everett L. Johnson propôs a utilização do método do quarto de quadrado num multiplicador digital.[11] Para formar o produto de dois inteiros de 8 bits, por exemplo, o dispositivo digital forma a soma e a diferença, procura ambas as quantidades numa tabela de quadrados, obtém a diferença dos resultados e divide por quatro deslocando dois bits para a direita. Para inteiros de 8 bits, a tabela de um quarto de quadrados terá entradas (uma entrada para o intervalo completo 0..510 de somas possíveis, usando as diferenças apenas as primeiras 256 entradas no intervalo 0..255) ou entradas (usando a técnica de complementos para 2 e máscara de 9 bits para diferenças negativas, a qual evita testar o sinal das diferenças), tendo cada entrada 16 bits de largura (os valores de entrada vão de (0²/4)=0 a (510²/4)=65025).

A técnica de multiplicação de um quarto de quadrado beneficiou sistemas de 8 bits que não dispunham de qualquer suporte para um multiplicador em hardware. Charles Putney implementou este método no 6502.[12]

Complexidade computacional da multiplicação

Predefinição:Problemas em aberto

Uma linha de investigação na ciência da computação teórica centra-se no número de operações aritméticas de bit único necessárias para multiplicar dois inteiros de bits. Isto é conhecido como a complexidade computacional da multiplicação. Os algoritmos habituais efetuados à mão possuem uma complexidade assintótica de , mas em 1960 Anatoly Karatsuba descobriu que era possível obter uma complexidade melhor (com o Algoritmo de Karatsuba).[13]

Atualmente, o algoritmo com a melhor complexidade computacional é um algoritmo de 2019 de David Harvey e Joris van der Hoeven, que utiliza as estratégias de usar transformadas teóricas dos números introduzidas pelo Algoritmo de Schönhage-Strassen para multiplicar inteiros usando apenas operações.[14] Conjetura-se que este seja o melhor algoritmo possível, mas os limites inferiores de não são conhecidos.

Multiplicação de Karatsuba

A multiplicação de Karatsuba é um algoritmo de divisão e conquista de , que utiliza a recursividade para unir subcálculos.

Ao reescrever a fórmula, torna-se possível efetuar subcálculos / recursão. Através da recursividade, é possível resolver isto de forma rápida.

Sejam e representados como cadeias de dígitos numa determinada base . Para qualquer inteiro positivo menor que , pode-se escrever os dois números dados como

onde e são menores que . O produto é então

onde

Estas fórmulas requerem quatro multiplicações e eram conhecidas por Charles Babbage.[15] Karatsuba observou que pode ser calculado em apenas três multiplicações, à custa de algumas adições extra. Com e como anteriormente, pode-se observar que

Devido à sobrecarga (overhead) da recursividade, a multiplicação de Karatsuba é mais lenta do que a multiplicação longa para pequenos valores de ; as implementações típicas, por conseguinte, mudam para a multiplicação longa para pequenos valores de .

Caso geral com multiplicação de N números

Ao explorar padrões após a expansão, observa-se o seguinte:

Cada parcela está associada a um número binário único de 0 a , por exemplo etc. Além disso; B é elevado à potência correspondente ao número de 1s nesta cadeia binária, multiplicado por m.

Se expressarmos isto em menos termos, obtemos:

, onde significa o dígito no número i na posição j. Note que

História

O algoritmo de Karatsuba foi o primeiro algoritmo conhecido para a multiplicação a ser assintoticamente mais rápido do que a multiplicação longa,[16] e pode, portanto, ser visto como o ponto de partida para a teoria das multiplicações rápidas.

Toom-Cook

Outro método de multiplicação é chamado de Toom-Cook ou Toom-3. O método de Toom-Cook divide cada número a ser multiplicado em múltiplas partes. O método de Toom-Cook é uma das generalizações do método de Karatsuba. Um Toom-Cook de três vias pode fazer uma multiplicação de tamanho 3N pelo custo de cinco multiplicações de tamanho N. Isto acelera a operação por um fator de 9/5, enquanto que o método de Karatsuba a acelera por 4/3.

Embora o uso de cada vez mais partes possa reduzir ainda mais o tempo gasto em multiplicações recursivas, a sobrecarga proveniente das adições e da gestão de dígitos também cresce. Por esta razão, o método das transformadas de Fourier é tipicamente mais rápido para números com vários milhares de dígitos, e assintoticamente mais rápido para números ainda maiores.

Schönhage-Strassen

Demonstração da multiplicação de 1234 × 5678 = 7006652 utilizando transformadas rápidas de Fourier (FFTs). São utilizadas transformadas teóricas dos números nos inteiros módulo 337, selecionando 85 como uma 8.ª raiz da unidade. A base 10 é utilizada em vez da base 2w para fins ilustrativos

Todo o número na base B pode ser escrito como um polinómio:

Além disso, a multiplicação de dois números pode ser pensada como o produto de dois polinómios:

Uma vez que o coeficiente de no produto é tem-se uma convolução, pelo que se pode utilizar a transformada rápida de Fourier (FFT):

Portanto, a multiplicação é reduzida a uma FFT, multiplicações e uma FFT inversa. Resulta numa complexidade de tempo de O(n log(n) log(log n)).

História

O algoritmo foi inventado por Strassen (1968). Tornou-se prático e foram-lhe fornecidas garantias teóricas em 1971 por Schönhage e Strassen, resultando no algoritmo de Schönhage-Strassen.[17]

Melhorias adicionais

Em 2007, a complexidade assintótica da multiplicação de inteiros foi melhorada pelo matemático suíço Martin Fürer da Universidade Estadual da Pensilvânia para utilizando transformadas de Fourier sobre números complexos,[18] onde log* denota o logaritmo iterado. Anindya De, Chandan Saha, Piyush Kurur e Ramprasad Saptharishi apresentaram um algoritmo semelhante utilizando aritmética modular em 2008, alcançando o mesmo tempo de execução.[19] No contexto do material acima referido, o que estes últimos autores conseguiram foi encontrar um N muito inferior a 23k + 1, de modo a que Z/NZ tenha uma (2m)-ésima raiz da unidade. Isto acelera o cálculo e reduz a complexidade de tempo. No entanto, estes algoritmos mais recentes só são mais rápidos do que o de Schönhage-Strassen para entradas de um tamanho impraticavelmente grande.

Em 2014, Harvey, Joris van der Hoeven e Lecerf[20] apresentaram um novo algoritmo que atinge um tempo de execução de , explicitando a constante implícita no expoente de . Eles também propuseram uma variante do seu algoritmo que alcança , mas cuja validade se baseia em conjeturas padrão sobre a distribuição dos primos de Mersenne. Em 2016, Covanov e Thomé propuseram um algoritmo de multiplicação de inteiros baseado numa generalização dos primos de Fermat que conjeturalmente atinge um limite de complexidade de . Isto iguala o resultado condicional de 2015 de Harvey, van der Hoeven e Lecerf, mas utiliza um algoritmo diferente e baseia-se numa conjetura diferente.[21] Em 2018, Harvey e van der Hoeven utilizaram uma abordagem baseada na existência de vetores curtos de reticulado garantidos pelo teorema de Minkowski para provar um limite de complexidade incondicional de .[22]

Em março de 2019, David Harvey e Joris van der Hoeven anunciaram a sua descoberta de um algoritmo de multiplicação de O(n log n).[23] Foi publicado nos Annals of Mathematics em 2021.[24] Pelo fato de Schönhage e Strassen terem previsto que n log(n) seria o "melhor resultado possível", Harvey disse: "... espera-se que o nosso trabalho seja o fim da linha para este problema, embora ainda não saibamos como o provar com rigor."[25]

Limites inferiores

Existe um limite inferior trivial de Ω(n) para multiplicar dois números de n bits num único processador; não é conhecido nenhum algoritmo correspondente (em máquinas convencionais, isto é, em máquinas equivalentes a Turing), nem qualquer limite inferior mais estrito. A conjetura de Hartmanis-Stearns implicaria que não pode ser alcançado. A multiplicação encontra-se fora de AC0[p] para qualquer primo p, o que significa que não existe nenhuma família de circuitos de profundidade constante e de tamanho polinomial (ou mesmo subexponencial) a utilizar portas AND, OR, NOT e MODp que consiga calcular um produto. Isto resulta de uma redução de profundidade constante de MODq à multiplicação.[26] Limites inferiores para a multiplicação também são conhecidos para algumas classes de programas de ramificação (branching programs).[27]

Multiplicação de números complexos

A multiplicação complexa envolve normalmente quatro multiplicações e duas adições.

Ou

Como observado por Peter Ungar em 1963, é possível reduzir o número de multiplicações para três, utilizando essencialmente o mesmo cálculo que o Algoritmo de Karatsuba.[28] O produto pode ser calculado da seguinte forma:


Este algoritmo utiliza apenas três multiplicações, em vez de quatro, e cinco adições ou subtrações, em vez de duas. Se uma multiplicação for mais dispendiosa do que três adições ou subtrações, como quando se calcula à mão, então existe um ganho de velocidade. Nos computadores modernos, uma multiplicação e uma adição podem demorar sensivelmente o mesmo tempo, pelo que pode não haver ganho de velocidade. Existe um compromisso (trade-off), uma vez que pode haver alguma perda de precisão ao utilizar cálculos em ponto flutuante.

Para transformadas rápidas de Fourier (FFTs) (ou qualquer transformação linear), as multiplicações complexas são por coeficientes constantes (chamados de fatores de rotação ou twiddle factors nas FFTs), caso em que duas das adições ( e ) podem ser pré-calculadas. Por conseguinte, são necessárias apenas três multiplicações e três adições.[29] No entanto, trocar uma multiplicação por uma adição desta forma pode já não ser tão benéfico com as modernas unidades de ponto flutuante.[30]

Multiplicação de polinómios

Todos os algoritmos de multiplicação acima também podem ser expandidos para multiplicar polinómios. Alternativamente, a técnica de substituição de Kronecker pode ser usada para converter o problema de multiplicação de polinómios numa única multiplicação binária.[31]

Os métodos de multiplicação longa podem ser generalizados para permitir a multiplicação de fórmulas algébricas:

 14ac - 3ab + 2 multiplicado por ac - ab + 1
 14ac  -3ab   2
   ac   -ab   1
 ————————————————————
 14a2c2  -3a2bc   2ac
        -14a2bc         3a2b2  -2ab
                 14ac           -3ab   2
 ———————————————————————————————————————
 14a2c2 -17a2bc   16ac  3a2b2    -5ab  +2
 =======================================[32]

Como outro exemplo de multiplicação baseada em colunas, considere a multiplicação de 23 toneladas longas (t), 12 quintais americanos/britânicos (cwt) e 2 quartos (qtr) por 47. Este exemplo utiliza medidas do sistema avoirdupois: 1 t = 20 cwt, 1 cwt = 4 qtr.

    t    cwt  qtr
   23     12    2
               47 ×
 ————————————————
1. Multiplicar tudo por 47
 1081    564   94
 ————————————————
2a. Transportar qtr e somar a cwt (94 = 23 × 4 + 2)
        (564)  94
          23    2
        —————
         587    2
2b. Transportar cwt e somar a t (587 = 29 × 20 + 7)
(1081)   587    2
   29      7
 ————————————————
3. Adição final
 1110      7    2
 =================  Resposta: 1110 t 7 cwt 2 qtr


A mesma disposição e métodos podem ser usados para quaisquer medidas tradicionais e moedas não decimais, como o antigo sistema britânico £sd (libras, xelins e pence).

Referências

  1. «Multiplication». www.mathematische-basteleien.de. Consultado em 15 de março de 2022
  2. Brent, Richard P (Março de 1978). «A Fortran Multiple-Precision Arithmetic Package.». ACM Transactions on Mathematical Software. 4: 57–70. CiteSeerX 10.1.1.117.8425Acessível livremente. doi:10.1145/355769.355775
  3. Eason, Gary (13 de fevereiro de 2000). «Back to school for parents». BBC News
    Eastaway, Rob (10 de setembro de 2010). «Why parents can't do maths today». BBC News
  4. Corlu, M.S.; Burlbaw, L.M.; Capraro, R.M.; Corlu, M.A.; Han, S. (2010). «The Ottoman Palace School Enderun and the Man with Multiple Talents, Matrakçı Nasuh». Journal of the Korea Society of Mathematical Education Series D: Research in Mathematical Education. 14 (1): 19–31
  5. Bogomolny, Alexander. «Peasant Multiplication». www.cut-the-knot.org. Consultado em 4 de novembro de 2017
  6. Wells, D. (1987). The Penguin Dictionary of Curious and Interesting Numbers. [S.l.]: Penguin Books. p. 44. ISBN 978-0-14-008029-2
  7. McFarland, David (2007). Quarter Tables Revisited: Earlier Tables, Division of Labor in Table Construction, and Later Implementations in Analog Computers. [S.l.: s.n.] p. 1
  8. Robson, Eleanor (2008). Mathematics in Ancient Iraq: A Social History. [S.l.]: Princeton University Press. p. 227. ISBN 978-0691201405
  9. Reviews. The Civil Engineer and Architect's Journal. [S.l.: s.n.] 1857. pp. 54–55.
  10. Holmes, Neville (2003). «Multiplying with quarter squares». The Mathematical Gazette. 87 (509): 296–299. JSTOR 3621048. doi:10.1017/S0025557200172778.
  11. Everett L., Johnson (Março de 1980). «A Digital Quarter Square Multiplier». Washington, DC, USA: IEEE Computer Society. IEEE Transactions on Computers. C–29 (3): 258–261. ISSN 0018-9340. doi:10.1109/TC.1980.1675558
  12. Putney, Charles (Março de 1986). «Fastest 6502 Multiplication Yet». Apple Assembly Line. 6 (6)
  13. «The Genius Way Computers Multiply Big Numbers». YouTube. 2 de janeiro de 2025
  14. Harvey, David; van der Hoeven, Joris (2021). «Integer multiplication in time » (PDF). Annals of Mathematics. Second Series. 193 (2): 563–617. MR 4224716. doi:10.4007/annals.2021.193.2.4
  15. Charles Babbage, Chapter VIII – Of the Analytical Engine, Larger Numbers Treated, Passages from the Life of a Philosopher, Longman Green, London, 1864; página 125.
  16. D. Knuth, The Art of Computer Programming, vol. 2, sec. 4.3.3 (1998)
  17. Schönhage, A.; Strassen, V. (1971). «Schnelle Multiplikation großer Zahlen». Computing. 7 (3–4): 281–292. doi:10.1007/BF02242355 Verifique o valor de |url-access=subscription (ajuda)
  18. Fürer, M. (2007). «Faster Integer Multiplication» (PDF). Proceedings of the thirty-ninth annual ACM symposium on Theory of computing, June 11–13, 2007, San Diego, California, USA. [S.l.: s.n.] pp. 57–66. ISBN 978-1-59593-631-8. doi:10.1145/1250790.1250800
  19. De, A.; Saha, C.; Kurur, P.; Saptharishi, R. (2008). «Fast integer multiplication using modular arithmetic». Proceedings of the 40th annual ACM Symposium on Theory of Computing (STOC). [S.l.: s.n.] pp. 499–506. ISBN 978-1-60558-047-0. arXiv:0801.1416Acessível livremente. doi:10.1145/1374376.1374447
  20. Harvey, David; van der Hoeven, Joris; Lecerf, Grégoire (2016). «Even faster integer multiplication». Journal of Complexity. 36: 1–30. MR 3530637. arXiv:1407.3360Acessível livremente. doi:10.1016/j.jco.2016.03.001
  21. Covanov, Svyatoslav; Thomé, Emmanuel (2019). «Fast Integer Multiplication Using Generalized Fermat Primes». Math. Comp. 88 (317): 1449–1477. arXiv:1502.02800Acessível livremente. doi:10.1090/mcom/3367
  22. Harvey, D.; van der Hoeven, J. (2019). «Faster integer multiplication using short lattice vectors». The Open Book Series. 2: 293–310. arXiv:1802.07932Acessível livremente. doi:10.2140/obs.2019.2.293
  23. Hartnett, Kevin (11 de abril de 2019). «Mathematicians Discover the Perfect Way to Multiply». Quanta Magazine. Consultado em 3 de maio de 2019
  24. Harvey, David; van der Hoeven, Joris (2021). «Integer multiplication in time » (PDF). Annals of Mathematics. Second Series. 193 (2): 563–617. MR 4224716. doi:10.4007/annals.2021.193.2.4
  25. Gilbert, Lachlan (4 de abril de 2019). «Maths whiz solves 48-year-old multiplication problem». UNSW. Consultado em 18 de abril de 2019
  26. Arora, Sanjeev; Barak, Boaz (2009). Computational Complexity: A Modern Approach. [S.l.]: Cambridge University Press. ISBN 978-0-521-42426-4
  27. Ablayev, F.; Karpinski, M. (2003). «A lower bound for integer multiplication on randomized ordered read-once branching programs» (PDF). Information and Computation. 186 (1): 78–89. doi:10.1016/S0890-5401(03)00118-4
  28. Knuth, Donald E. (1988). The Art of Computer Programming volume 2: Seminumerical algorithms. [S.l.]: Addison-Wesley. pp. 519, 706
  29. Duhamel, P.; Vetterli, M. (1990). «Fast Fourier transforms: A tutorial review and a state of the art» (PDF). Signal Processing. 19 (4): 259–299 Ver Seção 4.1. Bibcode:1990SigPr..19..259D. doi:10.1016/0165-1684(90)90158-U
  30. Johnson, S.G.; Frigo, M. (2007). «A modified split-radix FFT with fewer arithmetic operations» (PDF). IEEE Trans. Signal Process. 55 (1): 111–9 Ver Seção IV. Bibcode:2007ITSP...55..111J. doi:10.1109/TSP.2006.882087
  31. von zur Gathen, Joachim; Gerhard, Jürgen (1999), Modern Computer Algebra, ISBN 978-0-521-64176-0, Cambridge University Press, pp. 243–244.
  32. Castle, Frank (1900). Workshop Mathematics. London: MacMillan and Co. p. 74