Реализации алгоритмов/Алгоритм Евклида: различия между версиями
Тщательное оформление программного кода, примечаний, языки расположены в алфавитном порядке, добавлена программа для ПМК |
|||
Строка 1: | Строка 1: | ||
Далее приводятся реализации [[w:алгоритм Евклида|алгоритма Евклида]] для вычисления НОД на различных [[w:язык программирования|языках программирования]]. |
Далее приводятся реализации [[w:алгоритм Евклида|алгоритма Евклида]] для вычисления НОД на различных [[w:язык программирования|языках программирования]]. |
||
== |
==[[w:Бейсик|BASIC]]== |
||
===QBASIC, QuickBasic, VisualBasic (до версий с поддержкой .NET)=== |
|||
Алгоритм вычитанием |
|||
Деление с остатком, без рекурсии: |
|||
<source lang="basic"> |
|||
('''define''' gcd ('''lambda''' (a b) |
|||
Function GCD (a As Integer, b As Integer) As Integer |
|||
('''if''' (> a b) ('''gcd''' (- a b) b) |
|||
Dim d As Integer |
|||
('''if''' (< a b) ('''gcd''' a (- b a)) |
|||
Do While a <> 0 and b <> 0 |
|||
If a >=b Then |
|||
a = a mod b |
|||
== [[Ruby]] == |
|||
Else |
|||
b = b mod a |
|||
Функция в [[рекурсия|рекурсивном]] виде: |
|||
End If |
|||
Loop |
|||
<source lang="ruby"> |
|||
GCD = a + b |
|||
End Function |
|||
return a if b.zero? |
|||
gcd(b, a % b) |
|||
end |
|||
</source> |
</source> |
||
==[[w:C (язык программирования)|C]]== |
|||
Функция в нерекурсивном виде: |
|||
Тип T определён как <code>typedef … T;</code>, вместо <code>…</code> следует подставить любой целочисленный тип (<code>int</code>, <code>unsigned</code>, <code>short</code> и т. д.) |
|||
Деление с остатком, без рекурсии: |
|||
<source lang="ruby"> |
|||
<source lang="c"> |
|||
def gcd(a, b) |
|||
a, |
T gcd (T a, T b) { |
||
T c; |
|||
while (b) { |
|||
end |
|||
c = a % b; |
|||
a = b; |
|||
b = c; |
|||
} |
|||
return (a < 0) ? -a : a; |
|||
} |
|||
</source> |
</source> |
||
Более короткое решение: |
|||
Алгоритм вычитанием: |
|||
<source lang="c"> |
|||
T gcd (T a, T b) { |
|||
<source lang="ruby"> |
|||
while (b) |
|||
def gcd(a, b) |
|||
b ^= a ^= b ^= a %= b; |
|||
a |
return a; |
||
} |
|||
else |
|||
b -= a |
|||
end while a != b |
|||
a |
|||
end |
|||
</source> |
</source> |
||
Деление с остатком, рекурсия: |
|||
== [[PHP]] == |
|||
<source lang="c"> |
|||
T gcd (T a, T b) { |
|||
<source lang="php"> |
|||
return (b == 0) ? a : gcd(b, a % b); |
|||
function nod($a, $b) |
|||
} |
|||
{ |
|||
while ($a <> 0 && $b <> 0) { |
|||
if ($a > $b) |
|||
$a= $a % $b; |
|||
else |
|||
$b= $b % $a; |
|||
$nod= $a + $b; |
|||
} |
|||
return $nod; |
|||
} |
|||
echo nod(5,3); |
|||
</source> |
</source> |
||
Вычитание, без рекурсии: |
|||
== [[Python]] == |
|||
<source lang="c"> |
|||
T gcd (T a, T b) { |
|||
Функция в [[рекурсия|рекурсивном]] виде: |
|||
while (a != b) { |
|||
if (a > b) |
|||
<source lang="python"> |
|||
a -= b; |
|||
def gcd(a, b): |
|||
else |
|||
b -= a; |
|||
} |
|||
return a; |
|||
} |
|||
</source> |
</source> |
||
==[[w:C_Sharp|C#]]== |
|||
Функция в нерекурсивном виде: |
|||
Деление с остатком, без рекурсии: |
|||
<source lang=" |
<source lang="csharp"> |
||
int GCD (int a, int b) |
|||
{ |
|||
while b: |
|||
while (b != 0) |
|||
b = a % (a = b); |
|||
return a; |
|||
} |
|||
</source> |
</source> |
||
== |
==[[w:Erlang|Erlang]]== |
||
Деление с остатком, рекурсия: |
|||
Функция в [[рекурсия|рекурсивном]] виде: |
|||
<source lang="erlang"> |
|||
gcd(A, 0) -> A; |
|||
<source lang="perl"> |
|||
gcd(A, B) -> gcd(B, (A rem B)). |
|||
sub nod |
|||
{ |
|||
return $_[0] != 0 ? nod ( ( $_[1] % $_[0] ), $_[0] ) : $_[1]; |
|||
} |
|||
</source> |
</source> |
||
==[[w:F_Sharp|F#]]== |
|||
== Shell == |
|||
Деление с остатком, рекурсия: |
|||
<source lang="fsharp"> |
|||
Функция в [[рекурсия|рекурсивном]] виде: |
|||
let rec nod a b = |
|||
match b with |
|||
<source lang="bash"> |
|||
|0 -> a |
|||
nod ( |
|b -> nod b (a % b) |
||
n=1 a=$1 b=$2 |
|||
if [[ $a -ne 0 ]] |
|||
then |
|||
nod $(( $b % $a )) $a |
|||
let "n = $?" |
|||
else |
|||
let "n = $b" |
|||
fi |
|||
return $n |
|||
} |
|||
nod $1 $2 |
|||
echo "NOD is $?" |
|||
</source> |
</source> |
||
== |
==[[w:Forth (язык программирования)|Forth]] (диалект [[RetroForth]])== |
||
Деление с остатком, рекурсия: |
|||
<source lang=" |
<source lang="forth"> |
||
: GCD ( n1 n2 -- n ) tuck mod 0; GCD ; |
|||
int c; |
|||
while (b) { |
|||
c = a % b; |
|||
a = b; |
|||
b = c; |
|||
} |
|||
return fabs(a); |
|||
}</source> |
|||
Более короткое решение: |
|||
<source lang="c"> |
|||
int gcd(int a, int b) { |
|||
while(b) b^=a^=b^=a%=b; |
|||
return a; |
|||
}</source> |
|||
Та же функция в рекурсивном виде: |
|||
<source lang="c"> |
|||
int gcd(int a, int b) { |
|||
if (b == 0) return a; |
|||
return gcd(b, a % b); |
|||
}</source> |
|||
Немного короче: |
|||
<source lang="c"> int gcd(int a, int b) { |
|||
return b? gcd(b, a % b) : a; |
|||
} |
|||
</source> |
</source> |
||
==[[w:Haskell|Haskell]]== |
|||
Алгоритм вычитанием: |
|||
Деление с остатком, рекурсия: |
|||
<source lang="c"> |
|||
int gcd(int a, int b) { |
|||
while ( a != b) { |
|||
if (a > b) a -= b; |
|||
else b -= a; |
|||
} |
|||
return a; |
|||
}</source> |
|||
== [[Forth (язык программирования)|Форт]] (диалект [[RetroForth]]) == |
|||
Рекурсивный алгоритм |
|||
: НОД ( n1 n2 -- n ) tuck mod 0; НОД ; |
|||
== [[Haskell]] == |
|||
<source lang="haskell"> |
<source lang="haskell"> |
||
gcd :: Integral a => a -> a -> a |
gcd :: Integral a => a -> a -> a |
||
Строка 166: | Строка 105: | ||
</source> |
</source> |
||
== |
==[[w:Java|Java]]== |
||
Деление с остатком, без рекурсии: |
|||
Рекурсивный алгоритм |
|||
<source lang="java"> |
|||
public static <T> T gcd (T a, T b) { |
|||
while (b != 0) { |
|||
T c = a % b; |
|||
a = b; |
|||
b = c; |
|||
} |
|||
return a; |
|||
} |
|||
</source> |
|||
Также допустимы функции, аналогичные написанным выше на C, например так: |
|||
<source lang="fsharp"> |
|||
<source lang="java"> |
|||
let rec nod a b = |
|||
public static <T> gcd (T a, T b) { |
|||
match b with |
|||
while (b != 0) |
|||
b ^= a ^= b ^= a %= b; |
|||
return a; |
|||
} |
|||
</source> |
</source> |
||
''*короткая запись работает не корректно. Например при начальных значениях 34 и 9 уже на следующем шаге значения получаются 43 и 0...'' |
|||
Деление с остатком, рекурсия: |
|||
<source lang="java"> |
|||
public static <T> T gcd (T a, T b) { |
|||
return b == 0 ? a : gcd(b, a % b); |
|||
} |
|||
</source> |
|||
== |
==[[w:Паскаль (язык программирования)|Pascal]]== |
||
Тип T определён как <code>type T = …;</code>, вместо <code>…</code> следует подставить любой целочисленный тип (<code>Integer</code>, <code>Byte</code>, <code>LongInt</code> и т. д.) |
|||
ЗАДАЧА НОД(a, b: ЦЕЛ): ЦЕЛ; |
|||
УКАЗ |
|||
Деление с остатком, без рекурсии: |
|||
ПОКА (a # 0) И (b # 0) ВЫП |
|||
ЕСЛИ a >= b ТО |
|||
a := a ОСТАТОК b |
|||
ИНАЧЕ |
|||
b := b ОСТАТОК a |
|||
КОН |
|||
КОН; |
|||
ВОЗВРАТ a + b |
|||
КОН НОД; |
|||
== [[Паскаль (язык программирования)|Pascal]] == |
|||
Обычный алгоритм: |
|||
<source lang="pascal"> |
<source lang="pascal"> |
||
function GCD (a, b: T): T; |
|||
begin |
|||
while a * b <> 0 do |
while a * b <> 0 do |
||
if a > b |
if a > b then |
||
a := a mod b |
|||
else b:= b mod a; |
else |
||
b := b mod a; |
|||
gcd := a + b |
|||
end; |
|||
</source> |
</source> |
||
Более быстрый алгоритм: |
Более быстрый алгоритм: |
||
<source lang="pascal"> |
<source lang="pascal"> |
||
function GCD (a, b: T): T; |
|||
var c: T; |
|||
var |
|||
begin |
|||
t: LongInt; |
|||
while b > 0 do |
|||
begin |
|||
begin |
|||
c := a mod b; |
|||
begin |
|||
a := b; |
|||
b := c |
|||
end; |
|||
gcd := a |
|||
end; |
|||
nod := a; |
|||
end; |
|||
</source> |
</source> |
||
Деление с остатком, рекурсия: |
|||
В рекурсивном виде: |
|||
<source lang="pascal"> |
<source lang="pascal"> |
||
function gcd (a, b: T): T; |
|||
begin |
|||
if b = 0 then |
if b = 0 then |
||
gcd := a |
|||
else |
else |
||
gcd := gcd(b, a mod b) |
|||
end; |
|||
</source> |
</source> |
||
==[[w:Perl|Perl]]== |
|||
== [[Пролог (язык программирования)|Prolog]] == |
|||
Деление с остатком, рекурсия: |
|||
<source lang="perl"> |
|||
?GCD(a,b,x) |
|||
sub gcd { |
|||
return $_[0] != 0 ? gcd ( ( $_[1] % $_[0] ), $_[0] ) : $_[1]; |
|||
GCD(0,b,b) <- |
|||
GCD(a,0,a) <- |
|||
GCD(a,b,x) <- a >= b, m is a mod b, GCD(m, b, x) |
|||
GCD(a,b,x) <- a < b, m is b mod a, GCD(a, m, x) |
|||
=== [[SWI-Prolog]] === |
|||
gcd(0,B,B). |
|||
gcd(A,0,A). |
|||
gcd(A,B,X) :- A >= B, M is A mod B, gcd(M, B, X). |
|||
gcd(A,B,X) :- A < B, M is B mod A, gcd(A, M, X). |
|||
=== [[Erlang]] === |
|||
gcd(A, 0) -> A; |
|||
gcd(A, B) -> gcd(B, (A rem B)). |
|||
== [[Java]] == |
|||
<source lang="java"> |
|||
public class GCD { |
|||
public static int gcd(int a,int b) { |
|||
while (b !=0) { |
|||
int tmp = a%b; |
|||
a = b; |
|||
b = tmp; |
|||
} |
|||
return a; |
|||
} |
|||
} |
} |
||
</source> |
</source> |
||
==[[w:PHP|PHP]]== |
|||
Немного короче: |
|||
Деление с остатком, без рекурсии: |
|||
<source lang="java"> |
|||
<source lang="php"> |
|||
public class GCD { |
|||
function gcd ($a, $b) { |
|||
public static int gcd(int a,int b) { |
|||
while ($a <> 0 && $b <> 0) { |
|||
if ($a > $b) |
|||
$a = $a % $b; |
|||
else |
|||
$b = $b % $a; |
|||
$gcd = $a + $b; |
|||
} |
} |
||
return $gcd; |
|||
} |
} |
||
echo gcd(5, 3); |
|||
</source> |
</source> |
||
==[[w:Пролог (язык программирования)|Prolog]]== |
|||
Также допустимы функции, аналогичные написанным выше на C, например так: |
|||
Деление с остатком, рекурсия: |
|||
<source lang="java"> |
|||
<source lang="prolog"> |
|||
public class GCD { |
|||
?GCD(a,b,x) |
|||
public static int gcd(int a,int b) { |
|||
while(b!=0) b^=a^=b^=a%=b; |
|||
return a; |
|||
} |
|||
} |
|||
</source> |
|||
''*короткая запись работает не корректно. Например при начальных значениях 34 и 9 уже на следующем шаге значения получаются 43 и 0...'' |
|||
GCD(0,b,b) <- |
|||
== [[C#]] == |
|||
GCD(a,0,a) <- |
|||
GCD(a,b,x) <- a >= b, m is a mod b, GCD(m, b, x) |
|||
GCD(a,b,x) <- a < b, m is b mod a, GCD(a, m, x) |
|||
</code> |
|||
===[[w:SWI-Prolog]]=== |
|||
<source lang="csharp"> |
|||
Деление с остатком, рекурсия: |
|||
int gcd(int a, int b) |
|||
<source> |
|||
{ |
|||
gcd(0,B,B). |
|||
while (b != 0) |
|||
gcd(A,0,A). |
|||
b = a % (a = b); |
|||
return a; |
|||
gcd(A,B,X) :- A >= B, M is A mod B, gcd(M, B, X). |
|||
} |
|||
gcd(A,B,X) :- A < B, M is B mod A, gcd(A, M, X). |
|||
</source> |
</source> |
||
== |
==[[w:Python|Python]]== |
||
Деление с остатком, без рекурсии: |
|||
<source lang="python"> |
|||
def gcd (a, b): |
|||
while b: |
|||
a, b = b, a % b |
|||
return a |
|||
</source> |
|||
Деление с остатком, рекурсия: |
|||
<source lang="csharp"> |
|||
<source lang="python"> |
|||
Function NOD(a As Integer, b As Integer) As Integer |
|||
def gcd (a, b): |
|||
return a if b == 0 else gcd(b, a % b) |
|||
</source> |
|||
==[[:Ruby|Ruby]]== |
|||
Dim d As Integer |
|||
Деление с остатком, без рекурсии: |
|||
<source lang="ruby"> |
|||
def gcd (a, b) |
|||
a, b = b, a % b until b.zero? |
|||
a |
|||
end |
|||
</source> |
|||
Деление с остатком, рекурсия: |
|||
Do While a <> 0 and b <> 0 |
|||
<source lang="ruby"> |
|||
def gcd (a, b) |
|||
return a if b.zero? |
|||
gcd(b, a % b) |
|||
end |
|||
</source> |
|||
Вычитание, без рекурсии: |
|||
If a >=b Then |
|||
<source lang="ruby"> |
|||
a = a mod b |
|||
def gcd (a, b) |
|||
Else |
|||
if a > b |
|||
a -= b |
|||
End If |
|||
else |
|||
b -= a |
|||
end while a != b |
|||
a |
|||
end |
|||
</source> |
|||
==[[w:Scheme|Scheme]]== |
|||
Loop |
|||
Вычитание, рекурсия: |
|||
('''define''' gcd ('''lambda''' (a b) |
|||
('''if''' (> a b) ('''gcd''' (- a b) b) |
|||
('''if''' (< a b) ('''gcd''' a (- b a)) |
|||
a)))) |
|||
==Shell== |
|||
d = a + b |
|||
Деление с остатком, рекурсия: |
|||
<source lang="bash"> |
|||
gcd () { |
|||
n=1 a=$1 b=$2 |
|||
if [[ $a -ne 0 ]] |
|||
then |
|||
gcd $(( $b % $a )) $a |
|||
let "n = $?" |
|||
else |
|||
let "n = $b" |
|||
fi |
|||
return $n |
|||
} |
|||
gcd $1 $2 |
|||
End Function |
|||
echo "Greatest common divisor is $?" |
|||
</source> |
</source> |
||
==[[w:Глагол (язык программирования)|Глагол]]== |
|||
== Ассемблер == |
|||
Деление с остатком, без рекурсии: |
|||
=== ARM === |
|||
<source> |
|||
Алгоритм вычитанием |
|||
ЗАДАЧА НОД (a, b: ЦЕЛ): ЦЕЛ; |
|||
УКАЗ |
|||
ПОКА (a # 0) И (b # 0) ВЫП |
|||
ЕСЛИ a >= b ТО |
|||
a := a ОСТАТОК b |
|||
ИНАЧЕ |
|||
b := b ОСТАТОК a |
|||
КОН |
|||
КОН; |
|||
ВОЗВРАТ a + b |
|||
КОН НОД; |
|||
</source> |
|||
==Ассемблер== |
|||
===ARM=== |
|||
Вычитание, без рекурсии: |
|||
<source lang="arm"> |
<source lang="arm"> |
||
loop CMP Ri, Rj ; проверка условий NE (i != j), GT (i > j) и LT (i < j); |
loop CMP Ri, Rj ; проверка условий NE (i != j), GT (i > j) и LT (i < j); |
||
Строка 328: | Строка 318: | ||
</source> |
</source> |
||
=== |
===Z80=== |
||
Вычитание, без рекурсии: |
|||
Алгоритм вычитанием |
|||
<source lang="z80"> |
<source lang="z80"> |
||
GCD_DEHL: ;CALL Inputs: HL,DE; Output: DE |
GCD_DEHL: ;CALL Inputs: HL,DE; Output: DE |
||
Строка 342: | Строка 332: | ||
</source> |
</source> |
||
==Программируемые микрокалькуляторы «Электроника»== |
|||
== См. также == |
|||
Деление с остатком, без рекурсии. Корректно обрабатываются любые целые числа (включая 0 и отрицательные). В вычислениях участвуют только регистры стека. |
|||
Использование: <первое число> В↑ <второе число> В/О С/П (НОД на индикаторе). |
|||
===МК-52 / 61 / 152 / 161=== |
|||
<source> |
|||
00. Fx≠0 01. 13 02. ↔ 03. В↑ 04. FВx 05. ÷ 06. FВx 07. ↔ 08. K[x] 09. × |
|||
10. − 11. Fx=0 12. 02 13. + 14. K|x| 15. С/П |
|||
</source> |
|||
==См. также== |
|||
* [[../Бинарный алгоритм вычисления НОД/]] |
* [[../Бинарный алгоритм вычисления НОД/]] |
||
Версия от 10:32, 25 апреля 2017
Далее приводятся реализации алгоритма Евклида для вычисления НОД на различных языках программирования.
BASIC
QBASIC, QuickBasic, VisualBasic (до версий с поддержкой .NET)
Деление с остатком, без рекурсии:
Function GCD (a As Integer, b As Integer) As Integer
Dim d As Integer
Do While a <> 0 and b <> 0
If a >=b Then
a = a mod b
Else
b = b mod a
End If
Loop
GCD = a + b
End Function
C
Тип T определён как typedef … T;
, вместо …
следует подставить любой целочисленный тип (int
, unsigned
, short
и т. д.)
Деление с остатком, без рекурсии:
T gcd (T a, T b) {
T c;
while (b) {
c = a % b;
a = b;
b = c;
}
return (a < 0) ? -a : a;
}
Более короткое решение:
T gcd (T a, T b) {
while (b)
b ^= a ^= b ^= a %= b;
return a;
}
Деление с остатком, рекурсия:
T gcd (T a, T b) {
return (b == 0) ? a : gcd(b, a % b);
}
Вычитание, без рекурсии:
T gcd (T a, T b) {
while (a != b) {
if (a > b)
a -= b;
else
b -= a;
}
return a;
}
C#
Деление с остатком, без рекурсии:
int GCD (int a, int b)
{
while (b != 0)
b = a % (a = b);
return a;
}
Erlang
Деление с остатком, рекурсия:
gcd(A, 0) -> A;
gcd(A, B) -> gcd(B, (A rem B)).
F#
Деление с остатком, рекурсия:
let rec nod a b =
match b with
|0 -> a
|b -> nod b (a % b)
Forth (диалект RetroForth)
Деление с остатком, рекурсия:
: GCD ( n1 n2 -- n ) tuck mod 0; GCD ;
Haskell
Деление с остатком, рекурсия:
gcd :: Integral a => a -> a -> a
gcd 0 0 = error "НОД от 0 и 0 не определён."
gcd x y = gcd' (abs x) (abs y)
where gcd' x 0 = x
gcd' x y = gcd' y (x `rem` y)
Java
Деление с остатком, без рекурсии:
public static <T> T gcd (T a, T b) {
while (b != 0) {
T c = a % b;
a = b;
b = c;
}
return a;
}
Также допустимы функции, аналогичные написанным выше на C, например так:
public static <T> gcd (T a, T b) {
while (b != 0)
b ^= a ^= b ^= a %= b;
return a;
}
*короткая запись работает не корректно. Например при начальных значениях 34 и 9 уже на следующем шаге значения получаются 43 и 0...
Деление с остатком, рекурсия:
public static <T> T gcd (T a, T b) {
return b == 0 ? a : gcd(b, a % b);
}
Pascal
Тип T определён как type T = …;
, вместо …
следует подставить любой целочисленный тип (Integer
, Byte
, LongInt
и т. д.)
Деление с остатком, без рекурсии:
function GCD (a, b: T): T;
begin
while a * b <> 0 do
if a > b then
a := a mod b
else
b := b mod a;
gcd := a + b
end;
Более быстрый алгоритм:
function GCD (a, b: T): T;
var c: T;
begin
while b > 0 do
begin
c := a mod b;
a := b;
b := c
end;
gcd := a
end;
Деление с остатком, рекурсия:
function gcd (a, b: T): T;
begin
if b = 0 then
gcd := a
else
gcd := gcd(b, a mod b)
end;
Perl
Деление с остатком, рекурсия:
sub gcd {
return $_[0] != 0 ? gcd ( ( $_[1] % $_[0] ), $_[0] ) : $_[1];
}
PHP
Деление с остатком, без рекурсии:
function gcd ($a, $b) {
while ($a <> 0 && $b <> 0) {
if ($a > $b)
$a = $a % $b;
else
$b = $b % $a;
$gcd = $a + $b;
}
return $gcd;
}
echo gcd(5, 3);
Prolog
Деление с остатком, рекурсия:
?GCD(a,b,x)
GCD(0,b,b) <-
GCD(a,0,a) <-
GCD(a,b,x) <- a >= b, m is a mod b, GCD(m, b, x)
GCD(a,b,x) <- a < b, m is b mod a, GCD(a, m, x)
</code>
===[[w:SWI-Prolog]]===
Деление с остатком, рекурсия:
<source>
gcd(0,B,B).
gcd(A,0,A).
gcd(A,B,X) :- A >= B, M is A mod B, gcd(M, B, X).
gcd(A,B,X) :- A < B, M is B mod A, gcd(A, M, X).
Python
Деление с остатком, без рекурсии:
def gcd (a, b):
while b:
a, b = b, a % b
return a
Деление с остатком, рекурсия:
def gcd (a, b):
return a if b == 0 else gcd(b, a % b)
Ruby
Деление с остатком, без рекурсии:
def gcd (a, b)
a, b = b, a % b until b.zero?
a
end
Деление с остатком, рекурсия:
def gcd (a, b)
return a if b.zero?
gcd(b, a % b)
end
Вычитание, без рекурсии:
def gcd (a, b)
if a > b
a -= b
else
b -= a
end while a != b
a
end
Scheme
Вычитание, рекурсия:
(define gcd (lambda (a b) (if (> a b) (gcd (- a b) b) (if (< a b) (gcd a (- b a)) a))))
Shell
Деление с остатком, рекурсия:
gcd () {
n=1 a=$1 b=$2
if [[ $a -ne 0 ]]
then
gcd $(( $b % $a )) $a
let "n = $?"
else
let "n = $b"
fi
return $n
}
gcd $1 $2
echo "Greatest common divisor is $?"
Глагол
Деление с остатком, без рекурсии:
ЗАДАЧА НОД (a, b: ЦЕЛ): ЦЕЛ;
УКАЗ
ПОКА (a # 0) И (b # 0) ВЫП
ЕСЛИ a >= b ТО
a := a ОСТАТОК b
ИНАЧЕ
b := b ОСТАТОК a
КОН
КОН;
ВОЗВРАТ a + b
КОН НОД;
Ассемблер
ARM
Вычитание, без рекурсии:
loop CMP Ri, Rj ; проверка условий NE (i != j), GT (i > j) и LT (i < j);
SUBGT Ri, Ri, Rj ; если GT, выполняется i = i-j;
SUBLT Rj, Rj, Ri ; если LT, выполняется j = j-i;
BNE loop ; если NE - переход на метку loop.
Z80
Вычитание, без рекурсии:
GCD_DEHL: ;CALL Inputs: HL,DE; Output: DE
AND A ;сброс CF
LOOP:
SBC HL,DE ;совмещение трёх в одном - одного сравнения и поочередно двух вычитаний.
RET Z ;минимизация общего размера, поэтому в цикле.
JR NC,LOOP
ADD HL,DE ;откат лишнего вычитания
EX DE,HL
JR GCD_DEHL
Программируемые микрокалькуляторы «Электроника»
Деление с остатком, без рекурсии. Корректно обрабатываются любые целые числа (включая 0 и отрицательные). В вычислениях участвуют только регистры стека.
Использование: <первое число> В↑ <второе число> В/О С/П (НОД на индикаторе).
МК-52 / 61 / 152 / 161
00. Fx≠0 01. 13 02. ↔ 03. В↑ 04. FВx 05. ÷ 06. FВx 07. ↔ 08. K[x] 09. ×
10. − 11. Fx=0 12. 02 13. + 14. K|x| 15. С/П