умножение двух чисел - PullRequest
       38

умножение двух чисел

6 голосов
/ 12 февраля 2012

Несколько дней назад у меня было интервью с Qualcomm.Я был просто привязан к одному вопросу, вопрос, который ты выглядел очень простым, но ни я, ни интервьюер не были удовлетворены моими ответами, если кто-нибудь может дать какое-либо хорошее решение этой проблемы.

Вопрос:

Умножьте 2 числа без использования каких-либо циклов и сложений и, конечно, без умножения и деления.

На что я ответил: рекурсия

Он сказал что-то еще внизкий уровень.

К которому подлинная мысль, которая пришла мне в голову, была сдвигом битов, но сдвиг битов умножит число только на степень 2, а для других чисел нам, наконец, придется сложить.

Например: 10 * 7 можно сделать следующим образом: (двоичное число 7 ~~ 111) 10 << 2 + 10 << 1 + 10 40 + 20 + 10 = 70 </p>

Но опять сложение былоне допускается.

Любые мысли по этому вопросу, ребята.

Ответы [ 8 ]

7 голосов
/ 12 февраля 2012

Вот решение, использующее поиск, сложение и сдвиг. Поиск не требует умножения, так как это массив указателей на другой массив - следовательно, для нахождения нужного массива требуется сложение. Затем, используя второе значение, вы можете повторить арифметику указателя и получить результат поиска.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
  /* Note:As this is an array of pointers to an array of values, addition is
     only required for the lookup.

     i.e. 

     First part: lookup + a value -> A pointer to an array
     Second part - Add a value to the pointer to above pointer to get the value
  */
  unsigned char lookup[16][16] = {
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
    { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 },
    { 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45 },
    { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60 },
    { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75 },
    { 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90 },
    { 0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105 },
    { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 },
    { 0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108, 117, 126, 135 },
    { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150 },
    { 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121, 132, 143, 154, 165 },
    { 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180 },
    { 0, 13, 26, 39, 52, 65, 78, 91, 104, 117, 130, 143, 156, 169, 182, 195 },
    { 0, 14, 28, 42, 56, 70, 84, 98, 112, 126, 140, 154, 168, 182, 196, 210 },
    { 0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225 }
  };
  unsigned short answer, mult;
  unsigned char x, y, a, b;

  x = (unsigned char)atoi(argv[1]);
  y = (unsigned char)atoi(argv[2]);
  printf("Multiple %d by %d\n", x, y);

  answer = 0;
  /* First nibble of x, First nibble of y */
  a = x & 0xf;
  b = y & 0xf;
  mult = lookup[a][b];
  answer += mult;
  printf("Looking up %d, %d get %d - Answer so far %d\n", a, b, mult, answer);

  /* First nibble of x, Second nibble of y */
  a = x & 0xf;
  b = (y & 0xf0) >> 4;
  mult = lookup[a][b];
  answer += mult << 4;
  printf("Looking up %d, %d get %d - Answer so far %d\n", a, b, mult, answer);

  /* Second nibble of x, First nibble of y */
  a = (x & 0xf0) >> 4;
  b = y & 0xf;
  mult = lookup[a][b];
  answer += mult << 4;
  printf("Looking up %d, %d get %d - Answer so far %d\n", a, b, mult, answer);

  /* Second nibble of x, Second nibble of y */
  a = (x & 0xf0) >> 4;
  b = (y & 0xf0) >> 4;
  mult = lookup[a][b];
  answer += mult << 8;
  printf("Looking up %d, %d get %d - Answer so far %d\n", a, b, mult, answer);

  return 0;
} 
3 голосов
/ 12 февраля 2012

Возможно, вы могли бы рекурсивно добавлять, используя побитовые операции в качестве замены оператора сложения.См .: Добавление двух чисел с помощью побитовых операторов и операторов сдвига

2 голосов
/ 12 февраля 2012

Вы можете разделить свои проблемы, сначала реализовав сложение, а затем умножение на основе сложения.

Для сложения реализуйте то, что они делают на процессорах на уровне шлюза, используя побитовые операторы C:

http://en.wikipedia.org/wiki/Full_adder

Затем для умножения с реализованным добавлением используйте операторы и метки goto, чтобы не было операторов цикла (for, while и do будут использоваться итерационные выражения).

1 голос
/ 13 февраля 2012

Вместо этого вы можете использовать логарифмы и вычитания.

log (a * b) = log (a) + log (b)
a + b = - (- a-b)
exp (log (a)) = a

round(exp(-(-log(a)-log(b))))
1 голос
/ 12 февраля 2012

Вы можете реализовать сложение по битам операторов. Но все же, если вы хотите избежать циклов, вы должны написать много кода. (Я использовал для реализации умножения без арифметических операторов, но я использую цикл, смещая индекс, пока он не станет нулевым. Если это может помочь вам, скажите мне, и я буду искать файл)

1 голос
/ 12 февраля 2012

Как насчет умножения русских крестьян без сложения?Есть ли простой способ (несколько строк, без циклов) имитировать сложение, используя только AND, OR, XOR и NOT?

0 голосов
/ 12 февраля 2012

Вопрос: Умножение 2 чисел без использования циклов и сложений и, конечно, без умножения и деления.

Умножение определяется с точки зрения сложения. Нельзя не найти сложения в реализации умножения.

Числа произвольной точности не могут быть умножены без цикла / рекурсии.

Умножение двух чисел фиксированной длины битов может быть реализовано с помощью поиска в таблице. Проблема в размере таблицы. Генерация таблицы требует сложения.

Ответ: Это невозможно сделать.

0 голосов
/ 12 февраля 2012

Как насчет таблиц умножения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...