Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Умножение в паскале без использования стандартного оператора умножения

Автор: decompiler 8.01.2007 6:33

Здравствуйте, товарищи))))
Предложите, кто может, свои варианты решения: как написать программу, выполняющую умножение двух чисел (для вещественного и целочисленного типов), используя при этом:
1. Оператор сложения.
2. Оператор вычитания.
3. Оператор присваивания.
4. Условный оператор и оператор goto.
Заранее спасибо.


ЗЫ. прилагаю свой вариант:

Код

  var a,b,z:integer;

  function umn(x,y:integer):integer;
  var s,i:integer; label 1;
  begin
    s:=-y;
    i:=x;
    1: s:=s+y;
    if x>0 then
      begin
    x:=x-1;
    goto 1;
      end;
    if x<0 then
      begin
    x:=x+1;
    goto 1;
      end;
     if i<0 then s:=-s;
     if x=0 then umn:=s;
  end;

  begin
    readln(a,b);
    z:=umn(a,b);
    writeln(z);
  end.

Автор: мисс_граффити 8.01.2007 6:49

одна программа и для целых, и для вещественных? или две разные?

Автор: decompiler 8.01.2007 6:53

две разные

Автор: Malice 8.01.2007 15:28

Для целочисленных:

function mul (a,b:longint):longint;
var z,k:byte;
r:longint;
begin
z:=byte(a<0) xor byte (b<0);
a:=abs(a); b:=abs (B);
k:=0; r:=0;
while b>0 do begin
if (b and 1)=1 then r:=r+a shl k;
inc (k); b:=b shr 1;
end;
if z=1 then r:=-r;
mul:=r;
end;

Автор: мисс_граффити 8.01.2007 17:43

циклы нельзя... судя по условию

Автор: decompiler 8.01.2007 17:47

Цитата(Malice @ 8.01.2007 11:28) *

Для целочисленных:
function mul (a,b:longint):longint;
var z,k:byte;
r:longint;
begin
z:=byte(a<0) xor byte (b<0);
a:=abs(a); b:=abs (B);
k:=0; r:=0;
while b>0 do begin
if (b and 1)=1 then r:=r+a shl k;
inc (k); b:=b shr 1;
end;
if z=1 then r:=-r;
mul:=r;
end;



именно, циклы недоступны....

Автор: Malice 8.01.2007 17:55

Цитата(decompiler @ 8.01.2007 13:47) *

именно, циклы недоступны....

Можно испортить while через goto:

function mul (a,b:longint):longint;
var z,k:byte;
r:longint;
label 1,2;
begin
z:=byte(a<0) xor byte (b<0);
a:=abs(a); b:=abs (B);
k:=0; r:=0;
1: if b=0 then goto 2;
if (b and 1)=1 then r:=r+a shl k;
inc (k); b:=b shr 1;
goto 1;
2: if z=1 then r:=-r;
mul:=r;
end;

Автор: мисс_граффити 8.01.2007 18:44

а shl и xor ты через что испортишь? smile.gif

Автор: Malice 8.01.2007 18:56

Цитата(мисс_граффити @ 8.01.2007 14:44) *

а shl и xor ты через что испортишь? smile.gif

Опять просмотрел smile.gif Хотелось пооптимальней.. Тогда скатываемся к варианту автора, типа:
function mul (a,b:longint):longint;
var r:longint;
label 1,2;
begin
r:=0;
1: if b=0 then goto 2;
if b<0 then
begin r:=r-a; b:=b+1; end
else
begin r:=r+a; b:=b-1; end;
goto 1;
2: mul:=r;
end;


Автор: Malice 8.01.2007 21:23

Кто что придумал с вещественными ? У меня только с погрешностью вышло, а как точно, что-то не соображу..

Автор: Michael_Rybak 9.01.2007 4:15

Без погрешности-то и встроенное умножение не умеет smile.gif

Можно циклом выделять все цифры; сначала бинарным поиском узнать порядок каждого из чисел, а потом вычитать постепенно и перемножать всё друг на друга (все разряды первого на все разряды второго)

Хотя нет, с бинарным поиском я погорячился. Обычным циклом (т.е. вычисляем руками десятичный логарифм)

Автор: Malice 9.01.2007 4:55

Цитата(Michael_Rybak @ 9.01.2007 0:15) *

Без погрешности-то и встроенное умножение не умеет smile.gif

У меня уж больно большая - +/- 1. Знаю почему, но как точне сделать только сложениями пока не дошло sad.gif
Вот такой вариант:
function mul2(a,b:real):real;
var r:real;
z,s:real;
a1,a2:real;
k:byte;
label 1,2,6,7;
begin
{writeln (a*b:0:3);}
a1:=0; a2:=0; k:=0; s:=0; z:=0;
if a<0 then begin z:=1-z; a:=-a; end;
if b<0 then begin z:=1-z; b:=-b; end;
1: if a<1 then goto 2;
a:=a-1; a1:=a1+1;
goto 1;
2: a2:=a;
6: if a1<=0 then goto 7;
s:=s+b; a1:=a1-1;
goto 6;
7: a:=b; b:=a2;
k:=k+1; if k=1 then goto 1;
if z=1 then s:=-s;
mul2:=s;
end;

Были и другие, но уж больно на шифровку похожие..

Автор: Michael_Rybak 9.01.2007 7:48

Дальше нет смысла обсуждать, пока ОП не укажет границы входных (действительных) чисел и требуемую точность ответа. Еще вопрос: можно ли использовать массивы?

Цитата
Знаю почему, но как точне сделать только сложениями


Завести константу x = 2^(-много). И всё получится ;)

Автор: decompiler 9.01.2007 8:14

Цитата(Michael_Rybak @ 9.01.2007 3:48) *

Дальше нет смысла обсуждать, пока ОП не укажет границы входных (действительных) чисел и требуемую точность ответа. Еще вопрос: можно ли использовать массивы?


Массивы использовать можно.
Границы входных чисел, как и точность не устанавливаю - на ваше усмотрение.