Можно ли написать программу на C, которая умножает два числа без использования операторов умножения и сложения?
Я нашел это в переполнении стека . Пожалуйста, помогите этому бедному программисту с его проблемой. И, пожалуйста, не давайте ответы, как c = a/(1/((float)b))
, что точно так же, как c = a*b
. (И уже дан как ответ.)
Ответ с наибольшим количеством голосов 19 января 2014 года выигрывает.
Примечание: это вопрос кодового троллинга . Пожалуйста, не воспринимайте вопрос и / или ответы всерьез. Больше информации в коде троллинга .
Ответы:
Всегда используйте рекурсию
Отречение - верный путь!
источник
??::
без скобок, один для решения проблемы без попыток подправить правила;)inc
Функция проверяет свой аргумент, чтобы определить, является ли младший бит1
; если это так, он вызывает себя для оставшихся старших битов аргумента и возвращает результат с тем же0
самым младшим битом, который был проверен, будучи установленным , в то время как если нет (то есть младший бит равен0
), он заменяет его0
на a1
и возвращает результат , Процесс очень похож на то, что вы сделали бы, если бы вы добавляли значения вручную, двоичная цифра за двоичной цифрой.Вам придется каждый раз компилировать программу, но она действительно умножает любые натуральные числа точно в любой версии C или C ++.
источник
"%zu"
форматную строку.sizeof(char[A][B])
будет работать (если только A <= 0 или B <= 0 или A * B переполнены, в этом случае вы должны получить ошибку типа «плохой тип»)main(){return sizeof(char[A][B]);}
и вы скомпилируете, используяcc -DA=6 -DB=7 a.c; ./a.out; echo $?
Если вы в порядке с небольшой неточностью, вы можете использовать метод Монте-Карло :
Пример:
Я думаю, это может быть достаточно хорошо;)
источник
++
оператора.-= -1
|= 1
(будет работать на 50% номеров, в 100% случаев)printf
приращение:printf("%*cc%n\n", count, &count, 'c');
(Печатает «c» количество раз, затем еще один «c» и сохраняет количество символов, записанных обратноcount
.Поскольку вы не указали размер числа, я предполагаю, что вы имеете в виду два однобитных числа.
Если вы хотите максимально эффективную реализацию, используйте следующую крошечную реализацию:
Обратите внимание, что он по-прежнему принимает только биты, даже если типы являются неявными целыми числами - он требует меньше кода и, следовательно, более эффективен. (И да, он компилируется.)
источник
return a && b;
. Это короче, так быстрее.return a&b;
.#include<stdbool.h>
определитьtrue
иfalse
.#include<stdbool.h>
кажется, только три#define
с , что вы можете сделать сами (true
,false
,bool
и флаг , чтобы отметить , что он был активирован). Вы также можете взять трюк из одного из других ответов и использовать неявныйint
для «короткой» версии.Вот простой скрипт для этого:
ОБНОВЛЕНИЕ: Конечно, чтобы сделать это в C, просто оберните это
exec("bash", "-c", ...)
. (Спасибо, АмелияБР)источник
%20
чтобы избежать использования каких-либо+
знаков.) Но вам все равно нужно проанализировать вывод (в C), чтобы получить значение из него. Что будет особенно сложно, поскольку на выходе получается изображение, а не текст. Синтаксический анализ HTML и распознавание текста могут сделать это наилучшим возможным решением этой проблемы.Почему, давайте сделаем рекурсивный поиск пополам между INT64_MIN и INT64_MAX!
PS С удовольствием будет sigsegv с некоторыми значениями. ;)
источник
К сожалению, это работает только для целых чисел.
Поскольку добавление запрещено, сначала создадим оператор приращения:
Далее мы должны обработать знак. Сначала найдите бит знака:
Затем возьмите знак и величину каждого аргумента. Чтобы отменить число в дополнении до двух, инвертировать все биты и добавить один.
Чтобы умножить два натуральных числа, мы можем использовать геометрическое значение умножения:
тролли:
a++
действительно ли это считается дополнением? Бьюсь об заклад, учитель намеревался это позволить.<<
на самом деле умножение на степень два, так что это технически должно быть запрещено.-1
не самый хороший способ найти бит знака. Даже если бы не было встроенной константы, вы могли бы сделать логический сдвиг вправо на -1, а затем инвертировать все биты.MIN_INT
(АКАsignBit
) является отрицательным, это разрыв для этого значения. К счастью, это все еще работает в половине случаев, потому чтоMIN_INT * [even number]
должно быть ноль.Кроме того,plusOne
разрывы для-1
, вызывая бесконечные циклы каждый раз, когда результат переполняется.plusOne
работает просто отлично для любой стоимости. Извините за путаницу.источник
(x ^ y) | ((x & y) << 1)
не совсем работает, он не будет распространять информацию о переносе, когда x и y иРаботает и для чисел с плавающей точкой:
источник
Все знают, что Python проще в использовании, чем C. И Python имеет функции, соответствующие каждому оператору, для случаев, когда вы не можете использовать оператор. Каково именно наше определение проблемы, верно? Так:
источник
Ни один из других ответов не является теоретически обоснованным. Как сказано в самом первом комментарии к вопросу:
Нам нужно определить умножение и числа, прежде чем ответ станет возможным. Как только мы это сделаем, проблема станет тривиальной.
Самый популярный способ сделать это в начале математической логики - построить ординалы фон Неймана поверх теории множеств ZF , а затем использовать аксиомы Пеано .
Это естественным образом переводится в C, при условии, что у вас есть тип набора, который может содержать другие наборы. Он не должен содержать ничего, кроме наборов, что делает его тривиальным (ничего
void*
лишнего в большинстве библиотек наборов), поэтому я оставлю реализацию в качестве упражнения для читателя.Итак, сначала:
Если вы хотите расширить это до целых чисел, рациональных чисел, вещественных чисел и т. Д., Вы можете - с бесконечной точностью (при условии, что у вас бесконечная память и процессор) загружаться. Но, как сказал Кронекер, Бог создал натуральные числа; все остальное - дело человека, так зачем же беспокоиться?
источник
Если вы считаете, что [[b] хак - это мошенничество (поскольку это действительно дополнение), тогда это работает вместо этого. Но поиск таблиц также включает в себя добавления указателей.
См http://en.wikipedia.org/wiki/IBM_1620 - на самом деле , что компьютерный сделали сложение с использованием таблицы поиска ...
Что-то удовлетворяющее в использовании табличного механизма для «ускорения» операции, которая фактически может быть выполнена в одной инструкции.
источник
*
символ (хотя это не умножение)Я не уверен, что представляет собой «мошенничество» в этих сообщениях «тролля кода», но это умножает 2 произвольных целых числа во время выполнения без оператора
*
или+
оператора, использующего стандартные библиотеки (C99).источник
Мое решение троллей для
unsigned int
:источник
Здесь есть много хороших ответов, но не похоже, что многие из них пользуются тем, что современные компьютеры действительно мощные. В большинстве процессоров есть несколько процессоров, так зачем использовать только один? Мы можем использовать это, чтобы получить отличные результаты производительности.
Вот пример его использования:
#pragma omp parallel
Директива делает OpenMP разделить каждую часть для цикла к другому блоку исполнения, поэтому мы умножая параллельно!Обратите внимание, что вы должны использовать
-fopenmp
флаг, чтобы указать компилятору использовать OpenMP.Части тролля:
for
цикла - каждый поток запускает цикл.answer--
; в большинстве случаев это не будет отображаться, но иногда это приведет к неточным результатам.источник
К сожалению, умножение является очень сложной проблемой в информатике. Лучшее решение - использовать вместо этого разделение:
источник
В реальной жизни я обычно реагирую на троллинг со знанием, так что вот ответ, который совсем не троллит. Это работает для всех
int
значений, насколько я могу видеть.Насколько я понимаю, это очень похоже на то, как процессор может на самом деле делать целочисленное умножение. Во-первых, мы проверяем, что хотя бы один из аргументов (
a
) является положительным, переключая знак на оба, еслиa
он отрицательный (и нет, я отказываюсь считать отрицание своего рода сложением или умножением). Затемwhile (a)
цикл добавляет к результату сдвинутую копиюb
для каждого установленного битаa
.do
Петля реализует сr += x
использованием и, XOR, и смещение в том, что это явно набор половин сумматоров, с кэрри битами подается обратно вx
до тех пор, пока не более (реальный процессор будет использовать полные сумматоры, который является более эффективным, но C Безразлично» у нас есть операторы, которые нам нужны для этого, если не считать+
оператора).источник
while(a)
цикл никогда не заканчивается.источник
while(C/A != B || C%A)
?Бросив это в смесь:
Со страницы информации .
- Введение в код чего-то крайне недопустимого или неразумного, которое нельзя удалить, не выбрасывая все, что делает ответ совершенно бесполезным для ОП.
- […] Намерение состоит в том, чтобы сделать домашнее задание на языке, который ленивый ОП мог бы счесть приемлемым, но все же расстроил его.
источник
источник
Конечно:
Но, конечно, это обман; очевидно, он хочет иметь возможность снабжать два числа, верно?
источник
Там нет арифметики, как указатель арифметики:
Функция
f
реализует умножение.main
просто вызывает это с двумя аргументами.Работает и для отрицательных чисел.
источник
a
, да, отрицательно,b
я так не думаю. Но это поправимо многими творческими способами. Простейшим будет sign_a ^ = sign_b, sign_b = 0.C #
Я думаю, что вычитание и отрицание не допускаются ... Во всяком случае:
источник
C со встроенными SSE (потому что с SIMD все лучше):
Большим преимуществом этой реализации является то, что она может быть легко адаптирована для выполнения 4 параллельных умножений без
*
или,+
если требуется.источник
источник
strlen(cg) != a
как это очень троллинг метод для устранения--
(делает его O (N * N)).Наверное, слишком быстро :-(
источник
Эта версия на Haskell работает только с неотрицательными целыми числами, но она умножает так, как дети ее впервые изучают. Т.е. 3х4 - это 3 группы по 4 вещи. В этом случае подсчитываемые «вещи» - это метки ('|') на палочке.
источник
Это может работать в C99, если погода подходящая, и ваш компилятор поддерживает неопределенную чепуху.
источник
Поскольку OP не запрашивал C , вот один из них (Oracle) SQL!
источник
*
s!Может содержать следы УД.
источник
Тестовый забег:
источник