function ab2(a:integer; b:integer; var a2:integer; var ab:integer; var b2:integer);
var ca,cb,la,lb,d,m,d2:integer;
begin
ca:=bit_count(a);
cb:=bit_count(b);
if ca<2 then
a2:=a*a;ab:=a*b;b2:=sq(b);
elsif cb<2 then
a2:=sq(a);ab:=a*b;b2:=b*b;
end;
ca:=0;cb:=0;
while ca<la do
if bit_test(a,ca)=1 then
break;
end;
inc(ca);
end;
dec(la,ca);
if la<2 then
a2:=a*a;ab:=a*b;b2:=sq(b);
return;
end;
while cb<lb do
if bit_test(b,cb)=1 then
break;
end;
inc(cb);
end;
dec(lb,cb);
if lb<2 then
a2:=sq(a);
ab:=a*b;
b2:=b*b;
return;
end;
if a=b then
a2:=sq(a);ab:=a2;b2:=a2;
return;
end;
a:=bit_shift(a,-ca);
b:=bit_shift(b,-cb);
if a<b then
la:=lb-la-1;
if la>0 then
d:=b-bit_shift(a,la)
else
d:=b-a;
end;
ab2(a,d,a2,m,d2);
if la>0 then
ab:=bit_shift(a2,la)+m;
b2:=bit_shift(ab+m,la)+d2
else
ab:=a2+m;
b2:=ab+m+d2;
end;
else
lb:=la-lb-1;
if lb>0 then
d:=a-bit_shift(b,lb)
else
d:=a-b;
end;
ab2(b,d,b2,m,d2);
if lb>0 then
ab:=bit_shift(b2,lb)+m;
a2:=bit_shift(ab+m,lb)+d2
else
ab:=b2+m;
a2:=ab+m+d2;
end;
end;
if ca>0 then
a2:=bit_shift(a,bit_shift(ca,1));
end;
if cb>0 then
b2:=bit_shift(a,bit_shift(cb,1));
end;
m:=ca+cb;
if m>0 then
ab:=bit_shift(ab,m);
end;
end.
function sqm1(a:integer):integer; # модификация №1 нахождения квадратов
var al,ar,a2,b2,ab,n:integer;
begin
n:=bit_count(a);
if n<2 then return a*a end;
n:=bit_shift(bit_length(a),-1);
al:=bit_shift(a,-n);
ar:=a-bit_shift(al,n);
ab2(al,ar,a2,ab,b2);
return b2+bit_shift(ab,n+1)+bit_shift(a2,bit_shift(n,1));
end.