Modular inverse: Difference between revisions

m
(Add BCPL)
m (→‎{{header|Wren}}: Minor tidy)
 
(46 intermediate revisions by 17 users not shown)
Line 22:
{{trans|C}}
 
<langsyntaxhighlight lang="11l">F mul_inv(=a, =b)
V b0 = b
V x0 = 0
Line 36:
R x1
 
print(mul_inv(42, 2017))</langsyntaxhighlight>
 
{{out}}
Line 44:
 
=={{header|8th}}==
<syntaxhighlight lang="forth">
<lang Forth>
\ return "extended gcd" of a and b; The result satisfies the equation:
\ a*x + b*y = gcd(a,b)
Line 69:
 
42 2017 n:invmod . cr bye
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 76:
 
=={{header|Action!}}==
<langsyntaxhighlight Actionlang="action!">INT FUNC ModInverse(INT a,b)
INT t,nt,r,nr,q,tmp
 
Line 114:
Test(-486,217)
Test(40,2018)
RETURN</langsyntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Modular_inverse.png Screenshot from Atari 8-bit computer]
Line 127:
=={{header|Ada}}==
 
<syntaxhighlight lang="ada">
<lang Ada>
with Ada.Text_IO;use Ada.Text_IO;
procedure modular_inverse is
Line 147:
exception when others => Put_Line ("The inverse doesn't exist.");
end modular_inverse;
</syntaxhighlight>
</lang>
 
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang="algol68">
BEGIN
PROC modular inverse = (INT a, m) INT :
Line 186:
CO
END
</syntaxhighlight>
</lang>
{{out}}
<pre>42 ^ -1 (mod 2017) = 1969
Line 195:
{{trans|D}}
 
<langsyntaxhighlight lang="rebol">modInverse: function [a,b][
if b = 1 -> return 1
 
Line 211:
]
 
print modInverse 42 2017</langsyntaxhighlight>
 
{{out}}
 
<pre>1969</pre>
 
=={{header|ATS}}==
 
===Using allocated memory===
 
In addition to solving the task, I demonstrate some aspects of call-by-reference in ATS. In particular, ATS can distinguish ''at compile time'' between uninitialized and initialized variables.
 
The code is written as templates that will expand to code for any of the (non-dependent) signed integer types. In the main program, I use <code>llint</code> (typically exactly the same as <code>long long int</code> in C).
 
The return value of <code>inverse</code> is a linear optional value. It is allocated in the heap, used once, and freed.
 
<syntaxhighlight lang="ats">
(*
 
Using the algorithm described at
https://en.wikipedia.org/w/index.php?title=Extended_Euclidean_algorithm&oldid=1135569411#Modular_integers
 
*)
 
#include "share/atspre_staload.hats"
 
fn {tk : tkind}
division_with_nonnegative_remainder
(n : g0int tk, d : g0int tk,
(* q and r are called by reference, and start out
uninitialized. *)
q : &g0int tk? >> g0int tk,
r : &g0int tk? >> g0int tk)
: void =
let
(* The C optimizer most likely will reduce these these two
divisions to just one. They are simply synonyms for C '/' and
'%', and perform division that rounds the quotient towards
zero. *)
val q0 = g0int_div (n, d)
val r0 = g0int_mod (n, d)
in
(* The following calculation results in 'floor division', if the
divisor is positive, or 'ceiling division', if the divisor is
negative. This choice of method results in the remainder never
being negative. *)
if isgtez n || iseqz r0 then
(q := q0; r := r0)
else if isltz d then
(q := succ q0; r := r0 - d)
else
(q := pred q0; r := r0 + d)
end
 
fn {tk : tkind}
inverse (a : g0int tk, n : g0int tk) : Option_vt (g0int tk) =
let
typedef integer = g0int tk
 
fun
loop (t : integer, newt : integer,
r : integer, newr : integer) : Option_vt integer =
if iseqz newr then
begin
if r > g0i2i 1 then
None_vt ()
else if t < g0i2i 0 then
Some_vt (t + n)
else
Some_vt t
end
else
let
(* These become C variables. *)
var quotient : g0int tk?
var remainder : g0int tk?
 
(* Show the type AT COMPILE TIME. *)
prval _ = $showtype quotient
prval _ = $showtype remainder
 
val () =
division_with_nonnegative_remainder
(r, newr, quotient, remainder)
 
(* THE TYPES WILL HAVE CHANGED, because the storage is
initialized by the call to
division_with_nonnegative_remainder. *)
prval _ = $showtype quotient
prval _ = $showtype remainder
 
val t = newt
and newt = t - (quotient * newt)
and r = newr
and newr = remainder
in
loop (t, newt, r, newr)
end
in
loop (g0i2i 0, g0i2i 1, n, a)
end
 
implement
main0 () =
case+ inverse (42LL, 2017LL) of
| ~ None_vt () => println! "There is no inverse."
| ~ Some_vt value => println! value
</syntaxhighlight>
 
{{out}}
 
First compile the program:
<pre>$ patscc -DATS_MEMALLOC_LIBC -g -O2 modular-inverse.dats
**SHOWTYPE[UP]**(/home/trashman/src/chemoelectric/rosettacode-contributions/modular-inverse.dats: 1786(line=62, offs=31) -- 1794(line=62, offs=39)): S2Etop(knd=0; S2Eapp(S2Ecst(g0int_t0ype); S2Evar(tk(8481)))): S2RTbas(S2RTBASimp(1; t@ype))
**SHOWTYPE[UP]**(/home/trashman/src/chemoelectric/rosettacode-contributions/modular-inverse.dats: 1825(line=63, offs=31) -- 1834(line=63, offs=40)): S2Etop(knd=0; S2Eapp(S2Ecst(g0int_t0ype); S2Evar(tk(8481)))): S2RTbas(S2RTBASimp(1; t@ype))
**SHOWTYPE[UP]**(/home/trashman/src/chemoelectric/rosettacode-contributions/modular-inverse.dats: 2137(line=72, offs=31) -- 2145(line=72, offs=39)): S2Eapp(S2Ecst(g0int_t0ype); S2Evar(tk(8481))): S2RTbas(S2RTBASimp(1; t@ype))
**SHOWTYPE[UP]**(/home/trashman/src/chemoelectric/rosettacode-contributions/modular-inverse.dats: 2176(line=73, offs=31) -- 2185(line=73, offs=40)): S2Eapp(S2Ecst(g0int_t0ype); S2Evar(tk(8481))): S2RTbas(S2RTBASimp(1; t@ype))
</pre>
 
You may notice there is a subtle change in the type of <code>quotient</code> and <code>remainder</code>, once they have been initialized. ATS is making it safe ''not'' to initialize variables (with phony values) when you declare them.
 
Now run the program:
<pre>$ ./a.out
1969</pre>
 
===Safely avoiding the need for an allocator===
 
Here I demonstrate an optional value that requires no runtime overhead at all, but which is safe. If there is no inverse, then the compiler knows that <code>inverse_value</code> is still uninitialized, and will not let you use its value. (Try it and see.)
 
<syntaxhighlight lang="ats">
(*
Using the algorithm described at
https://en.wikipedia.org/w/index.php?title=Extended_Euclidean_algorithm&oldid=1135569411#Modular_integers
*)
 
#include "share/atspre_staload.hats"
 
fn {tk : tkind}
division_with_nonnegative_remainder
(n : g0int tk, d : g0int tk,
(* q and r are called by reference, and start out
uninitialized. *)
q : &g0int tk? >> g0int tk,
r : &g0int tk? >> g0int tk)
: void =
let
(* The C optimizer most likely will reduce these these two
divisions to just one. They are simply synonyms for C '/' and
'%', and perform division that rounds the quotient towards
zero. *)
val q0 = g0int_div (n, d)
val r0 = g0int_mod (n, d)
in
(* The following calculation results in 'floor division', if the
divisor is positive, or 'ceiling division', if the divisor is
negative. This choice of method results in the remainder never
being negative. *)
if isgtez n || iseqz r0 then
(q := q0; r := r0)
else if isltz d then
(q := succ q0; r := r0 - d)
else
(q := pred q0; r := r0 + d)
end
 
fn {tk : tkind}
inverse (a : g0int tk, n : g0int tk,
inverse_exists : &bool? >> bool exists,
inverse_value : &g0int tk? >> opt (g0int tk, exists))
: #[exists: bool] void =
let
typedef integer = g0int tk
 
fun
loop (t : integer, newt : integer,
r : integer, newr : integer,
inverse_exists : &bool? >> bool exists,
inverse_value : &g0int tk? >> opt (g0int tk, exists))
: #[exists: bool] void =
if iseqz newr then
begin
if r > g0i2i 1 then
let
val () = inverse_exists := false
prval () = opt_none inverse_value
in
end
else if t < g0i2i 0 then
let
val () = inverse_exists := true
val () = inverse_value := t + n
prval () = opt_some inverse_value
in
end
else
let
val () = inverse_exists := true
val () = inverse_value := t
prval () = opt_some inverse_value
in
end
end
else
let
(* These become C variables. *)
var quotient : g0int tk?
var remainder : g0int tk?
 
val () =
division_with_nonnegative_remainder
(r, newr, quotient, remainder)
 
val t = newt
and newt = t - (quotient * newt)
and r = newr
and newr = remainder
in
loop (t, newt, r, newr, inverse_exists, inverse_value)
end
in
loop (g0i2i 0, g0i2i 1, n, a, inverse_exists, inverse_value)
end
 
implement
main0 () =
let
var inverse_exists : bool?
var inverse_value : llint?
in
inverse (42LL, 2017LL, inverse_exists, inverse_value);
if inverse_exists then
let
prval () = opt_unsome inverse_value
in
println! inverse_value
end
else
let
prval () = opt_unnone inverse_value
in
println! "There is no inverse."
end
end
</syntaxhighlight>
 
{{out}}
There is no need to tell patscc what allocator to use, because none is used.
<pre>$ patscc -g -O2 modular-inverse-noheap.dats && ./a.out
1969</pre>
 
=={{header|AutoHotkey}}==
Translation of [http://rosettacode.org/wiki/Modular_inverse#C C].
<langsyntaxhighlight AutoHotkeylang="autohotkey">MsgBox, % ModInv(42, 2017)
 
ModInv(a, b) {
Line 237 ⟶ 481:
x1 += b0
return x1
}</langsyntaxhighlight>
{{out}}
<pre>1969</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f MODULAR_INVERSE.AWK
# converted from C
Line 270 ⟶ 514:
return(x1)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 279 ⟶ 523:
==={{header|ASIC}}===
{{trans|Pascal}}
<langsyntaxhighlight lang="basic">
REM Modular inverse
E = 42
Line 289 ⟶ 533:
CalcModInv:
REM Increments E Step times until Bal is greater than T
REM Repeats until Bal = 1 (MOD = 1) and returns Count
REM Bal will not be greater than T + E
D = 0
Line 309 ⟶ 553:
ModInv = D
RETURN
</syntaxhighlight>
</lang>
{{out}}
<pre>
1969
</pre>
 
==={{header|BASIC256}}===
<syntaxhighlight lang="basic">print multInv(42, 2017)
end
 
function multInv(a,b)
x0 = 0
b0 = b
multInv = 1
if b = 1 then return
while a > 1
q = a / b
t = b
b = a mod b
a = t
t = x0
x0 = multInv - q * x0
multInv = int(t)
end while
if multInv < 0 then return multInv + b0
end function</syntaxhighlight>
{{out}}
<pre>1969</pre>
 
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
{{works with|QBasic}}
{{trans|BASIC256}}
<syntaxhighlight lang="qbasic">10 CLS
20 CALL modularinverse(42, 2017)
30 CALL modularinverse(40, 1)
40 END
50 SUB modularinverse(e,t)
60 d = 0
70 IF e < t THEN
80 b = e
90 c = 1
100 WHILE b > 1
110 s = INT(((t-b)/e)+1)
120 b = b+s*e
130 c = c+s
140 b = b-t
150 WEND
160 d = c
170 ENDIF
180 m = d
190 PRINT m
200 END SUB</syntaxhighlight>
 
==={{header|Minimal BASIC}}===
{{trans|Pascal}}
{{works with|Applesoft BASIC}}
{{works with|Commodore BASIC|3.5}}
{{works with|Nascom ROM BASIC|4.7}}
<syntaxhighlight lang="gwbasic">
10 REM Modular inverse
20 LET E = 42
30 LET T = 2017
40 GOSUB 500
50 PRINT M
60 END
490 REM Calculate modular inverse
500 LET D = 0
510 IF E >= T THEN 600
520 LET B = E
530 LET C = 1
540 LET S1 = INT((T-B)/E)+1
550 LET B = B+S1*E
560 LET C = C+S1
570 LET B = B-T
580 IF B <> 1 THEN 540
590 LET D = C
600 LET M = D
610 RETURN
</syntaxhighlight>
 
==={{header|QBasic}}===
The [[#Chipmunk_Basic|Chipmunk Basic]] solution works without any changes.
<syntaxhighlight lang="qbasic"></syntaxhighlight>
 
==={{header|True BASIC}}===
<syntaxhighlight lang="qbasic">SUB modularinverse(e,t)
LET d = 0
IF e < t then
LET b = e
LET c = 1
DO WHILE b > 1
LET s = int(((t-b)/e)+1)
LET b = b+s*e
LET c = c+s
LET b = b-t
LOOP
LET d = c
END IF
LET m = d
PRINT m
END SUB
 
CALL modularinverse(42,2017)
CALL modularinverse(40,1)
END</syntaxhighlight>
 
=={{header|Batch File}}==
Line 319 ⟶ 664:
 
{{trans|Perl}}
<langsyntaxhighlight lang="dos">@echo off
setlocal enabledelayedexpansion
%== Calls the "function" ==%
Line 361 ⟶ 706:
if !t! lss 0 set /a t+=b
set %3=!t!
goto :EOF</langsyntaxhighlight>
{{Out}}
<pre>1969
Line 370 ⟶ 715:
 
=={{header|BCPL}}==
<langsyntaxhighlight lang="bcpl">get "libhdr"
 
let mulinv(a, b) =
Line 400 ⟶ 745:
show(-486, 217)
show(40, 2018)
$)</langsyntaxhighlight>
{{out}}
<pre>42, 2017 -> 1969
Line 410 ⟶ 755:
=={{header|Bracmat}}==
{{trans|Julia}}
<langsyntaxhighlight lang="bracmat">( ( mod-inv
= a b b0 x0 x1 q
. !arg:(?a.?b)
Line 425 ⟶ 770:
)
& out$(mod-inv$(42.2017))
};</langsyntaxhighlight>
Output
<pre>1969</pre>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
 
int mul_inv(int a, int b)
Line 449 ⟶ 794:
printf("%d\n", mul_inv(42, 2017));
return 0;
}</langsyntaxhighlight>
 
The above method has some problems. Most importantly, when given a pair (a,b) with no solution, it generates an FP exception. When given <tt>b=1</tt>, it returns 1 which is not a valid result mod 1. When given negative a or b the results are incorrect. The following generates results that should match Pari/GP for numbers in the int range.
{{trans|Perl}}
<langsyntaxhighlight lang="c">#include <stdio.h>
 
int mul_inv(int a, int b)
Line 477 ⟶ 822:
printf("%d\n", mul_inv(40, 2018));
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 488 ⟶ 833:
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="csharp">public class Program
{
static void Main()
Line 511 ⟶ 856:
return x < 0 ? x + m0 : x;
}
}</langsyntaxhighlight>
 
=={{header|C++}}==
===Iterative implementation===
{{trans|C}}
<langsyntaxhighlight lang="cpp">#include <iostream>
int mul_inv(int a, int b)
Line 535 ⟶ 880:
std::cout << mul_inv(42, 2017) << std::endl;
return 0;
}</langsyntaxhighlight>
 
===Recursive implementation===
<langsyntaxhighlight lang="cpp">#include <iostream>
 
short ObtainMultiplicativeInverse(int a, int b, int s0 = 1, int s1 = 0)
Line 549 ⟶ 894:
std::cout << ObtainMultiplicativeInverse(42, 2017) << std::endl;
return 0;
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="lisp">(ns test-p.core
(:require [clojure.math.numeric-tower :as math]))
 
Line 596 ⟶ 941:
(println (mul_inv 40 2018))
 
</syntaxhighlight>
</lang>
 
'''Output:'''
Line 609 ⟶ 954:
=={{header|CLU}}==
{{trans|Perl}}
<langsyntaxhighlight lang="clu">mul_inv = proc (a, b: int) returns (int) signals (no_inverse)
if b<0 then b := -b end
if a<0 then a := b - (-a // b) end
Line 644 ⟶ 989:
end
end
end start_up</langsyntaxhighlight>
{{out}}
<pre>42, 2017 -> 1969
Line 651 ⟶ 996:
-486, 217 -> 121
40, 2018 -> no modular inverse</pre>
 
=={{header|Comal}}==
<syntaxhighlight lang="comal">0010 FUNC mulinv#(a#,b#) CLOSED
0020 IF b#<0 THEN b#:=-b#
0030 IF a#<0 THEN a#:=b#-(-a# MOD b#)
0040 t#:=0;nt#:=1;r#:=b#;nr#:=a# MOD b#
0050 WHILE nr#<>0 DO
0060 q#:=r# DIV nr#
0070 tmp#:=nt#;nt#:=t#-q#*nt#;t#:=tmp#
0080 tmp#:=nr#;nr#:=r#-q#*nr#;r#:=tmp#
0090 ENDWHILE
0100 IF r#>1 THEN RETURN -1
0110 IF t#<0 THEN t#:+b#
0120 RETURN t#
0130 ENDFUNC mulinv#
0140 //
0150 WHILE NOT EOD DO
0160 READ a#,b#
0170 PRINT a#,", ",b#," -> ",mulinv#(a#,b#)
0180 ENDWHILE
0190 END
0200 //
0210 DATA 42,2017,40,1,52,-217,-486,217,40,2018</syntaxhighlight>
{{out}}
<pre>42, 2017 -> 1969
40, 1 -> 0
52, -217 -> 96
-486, 217 -> 121
40, 2018 -> -1</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">
;;
;; Calculates the GCD of a and b based on the Extended Euclidean Algorithm. The function also returns
Line 677 ⟶ 1,051:
(unless (= 1 r) (error "invmod: Values ~a and ~a are not coprimes." a m))
s))
</syntaxhighlight>
</lang>
 
{{out}}
Line 688 ⟶ 1,062:
1969
</pre>
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
 
sub mulinv(a: int32, b: int32): (t: int32) is
if b<0 then b := -b; end if;
if a<0 then a := b - (-a % b); end if;
t := 0;
var nt: int32 := 1;
var r := b;
var nr := a % b;
while nr != 0 loop
var q := r / nr;
var tmp := nt; nt := t - q*nt; t := tmp;
tmp := nr; nr := r - q*nr; r := tmp;
end loop;
if r>1 then t := -1;
elseif t<0 then t := t + b;
end if;
end sub;
 
record Pair is
a: int32;
b: int32;
end record;
 
var data: Pair[] := {
{42, 2017},
{40, 1},
{52, -217},
{-486, 217},
{40, 2018}
};
 
var i: @indexof data := 0;
while i < @sizeof data loop
print_i32(data[i].a as uint32);
print(", ");
print_i32(data[i].b as uint32);
print(" -> ");
var mi := mulinv(data[i].a, data[i].b);
if mi<0
then print("no inverse");
else print_i32(mi as uint32);
end if;
print_nl();
i := i + 1;
end loop;</syntaxhighlight>
{{out}}
<pre>42, 2017 -> 1969
40, 1 -> 0
52, 4294967079 -> 96
4294966810, 217 -> 121
40, 2018 -> no inverse</pre>
 
=={{header|Craft Basic}}==
<syntaxhighlight lang="basic">let e = 42
let t = 2017
 
gosub modularinverse
 
end
 
sub modularinverse
 
let d = 0
 
if e < t then
 
let b = e
let c = 1
 
do
 
let s = int(((t - b) / e) + 1)
let b = b + s * e
let c = c + s
let b = b - t
 
loop b <> 1
 
let d = c
 
endif
 
let m = d
 
print m
 
return</syntaxhighlight>
{{out| Output}}<pre>1969</pre>
 
=={{header|Crystal}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="ruby">def modinv(a0, m0)
return 1 if m0 == 1
a, m = a0, m0
Line 702 ⟶ 1,167:
inv += m0 if inv < 0
inv
end</langsyntaxhighlight>
 
{{out}}
Line 711 ⟶ 1,176:
=={{header|D}}==
{{trans|C}}
<langsyntaxhighlight lang="d">T modInverse(T)(T a, T b) pure nothrow {
if (b == 1)
return 1;
Line 733 ⟶ 1,198:
import std.stdio;
writeln(modInverse(42, 2017));
}</langsyntaxhighlight>
{{out}}
<pre>1969</pre>
Line 739 ⟶ 1,204:
{{trans|C}}
This solution prints the inverse <code>u</code> only if it exists (<code>a*u = 1 mod m</code>).
<syntaxhighlight lang="dc">
<lang dc>
dc -e "[m=]P?dsm[a=]P?dsa1sv[dsb~rsqlbrldlqlv*-lvsdsvd0<x]dsxxldd[dlmr+]sx0>xdla*lm%[p]sx1=x"
</syntaxhighlight>
</lang>
If <code>~</code> is not implemented, it can be replaced by <code>SdSnlnld/LnLd%</code>.
 
Line 767 ⟶ 1,232:
=={{header|Delphi}}==
See [[#Pascal]].
 
=={{header|Draco}}==
<syntaxhighlight lang="draco">proc mulinv(int a, b) int:
int t, nt, r, nr, q, tmp;
if b<0 then b := -b fi;
if a<0 then a := b - (-a % b) fi;
t := 0; nt := 1; r := b; nr := a % b;
while nr /= 0 do
q := r / nr;
tmp := nt; nt := t - q*nt; t := tmp;
tmp := nr; nr := r - q*nr; r := tmp
od;
if r>1 then -1
elif t<0 then t+b
else t
fi
corp
 
proc show(int a, b) void:
int mi;
mi := mulinv(a, b);
if mi>=0
then writeln(a:5, ", ", b:5, " -> ", mi:5)
else writeln(a:5, ", ", b:5, " -> no inverse")
fi
corp
 
proc main() void:
show(42, 2017);
show(40, 1);
show(52, -217);
show(-486, 217);
show(40, 2018)
corp</syntaxhighlight>
{{out}}
<pre> 42, 2017 -> 1969
40, 1 -> 0
52, -217 -> 96
-486, 217 -> 121
40, 2018 -> no inverse</pre>
 
=={{header|EasyLang}}==
{{trans|AWK}}
<syntaxhighlight lang="easylang">
func mod_inv a b .
b0 = b
x1 = 1
if b = 1
return 1
.
while a > 1
q = a div b
t = b
b = a mod b
a = t
t = x0
x0 = x1 - q * x0
x1 = t
.
if x1 < 0
x1 += b0
.
return x1
.
print mod_inv 42 2017
</syntaxhighlight>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
(lib 'math) ;; for egcd = extended gcd
 
Line 780 ⟶ 1,311:
(mod-inv 42 666)
🔴 error: not-coprimes (42 666)
</syntaxhighlight>
</lang>
 
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule Modular do
def extended_gcd(a, b) do
{last_remainder, last_x} = extended_gcd(abs(a), abs(b), 1, 0, 0, 1)
Line 804 ⟶ 1,335:
end
 
IO.puts Modular.inverse(42,2017)</langsyntaxhighlight>
 
{{out}}
Line 812 ⟶ 1,343:
 
=={{header|ERRE}}==
<langsyntaxhighlight ERRElang="erre">PROGRAM MOD_INV
 
!$INTEGER
Line 838 ⟶ 1,369:
MUL_INV(40,2018->T) PRINT(T)
END PROGRAM
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 849 ⟶ 1,380:
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">
// Calculate the inverse of a (mod m)
// See here for eea specs:
Line 861 ⟶ 1,392:
eea t' (t - div * t') r' (r - div * r')
(m + eea 0 1 m a) % m
</syntaxhighlight>
</lang>
{{in}}
<pre>
Line 873 ⟶ 1,404:
 
=={{header|Factor}}==
<syntaxhighlight lang="text">USE: math.functions
42 2017 mod-inv</langsyntaxhighlight>
{{out}}
<pre>
Line 882 ⟶ 1,413:
=={{header|Forth}}==
ANS Forth with double-number word set
<langsyntaxhighlight lang="forth">
: invmod { a m | v b c -- inv }
m to v
Line 893 ⟶ 1,424:
repeat b m mod dup to b 0<
if m b + else b then ;
</syntaxhighlight>
</lang>
ANS Forth version without locals
<langsyntaxhighlight lang="forth">
: modinv ( a m - inv)
dup 1- \ a m (m != 1)?
Line 914 ⟶ 1,445:
nip \ inv
;
</syntaxhighlight>
</lang>
<pre>
42 2017 invmod . 1969
42 2017 modinv . 1969
</pre>
 
=={{header|Fortran}}==
<syntaxhighlight lang="fortran">
program modular_inverse_task
 
implicit none
 
write (*,*) inverse (42, 2017)
 
contains
 
! Returns -1 if there is no inverse. I assume n > 0. The algorithm
! is described at
! https://en.wikipedia.org/w/index.php?title=Extended_Euclidean_algorithm&oldid=1135569411#Modular_integers
function inverse (a, n) result (inverse_value)
integer, intent(in) :: a, n
integer :: inverse_value
 
integer :: t, newt
integer :: r, newr
integer :: quotient, remainder, tmp
 
if (n <= 0) error stop
t = 0; newt = 1
r = n; newr = a
do while (newr /= 0)
remainder = modulo (r, newr) ! Floor division.
quotient = (r - remainder) / newr
tmp = newt; newt = t - (quotient * newt); t = tmp
r = newr; newr = remainder
end do
if (r > 1) then
inverse_value = -1
else if (t < 0) then
inverse_value = t + n
else
inverse_value = t
end if
end function inverse
 
end program modular_inverse_task
</syntaxhighlight>
 
{{out}}
<pre>$ gfortran -Wall -Wextra modular_inverse_task.f90 && ./a.out
1969
</pre>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 10-07-2018
' compile with: fbc -s console
 
Line 995 ⟶ 1,573:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>a * 42 + b * 2017 = GCD(42, 2017) = 1
Line 1,017 ⟶ 1,595:
 
=={{header|Frink}}==
<syntaxhighlight lang ="frink">println[modInverse[42, 2017]]</langsyntaxhighlight>
{{out}}
<pre>
Line 1,024 ⟶ 1,602:
 
=={{header|FunL}}==
<langsyntaxhighlight lang="funl">import integers.egcd
 
def modinv( a, m ) =
Line 1,035 ⟶ 1,613:
if res < 0 then res + m else res
 
println( modinv(42, 2017) )</langsyntaxhighlight>
 
{{out}}
Line 1,045 ⟶ 1,623:
=={{header|Go}}==
The standard library function uses the extended Euclidean algorithm internally.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,057 ⟶ 1,635:
k := new(big.Int).ModInverse(a, m)
fmt.Println(k)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,066 ⟶ 1,644:
{{trans|Pascal}}
{{works with|PC-BASIC|any}}
<langsyntaxhighlight lang="qbasic">
10 ' Modular inverse
20 LET E% = 42
Line 1,094 ⟶ 1,672:
1140 LET MODINV% = D%
1150 RETURN
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,101 ⟶ 1,679:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">-- Given a and m, return Just x such that ax = 1 mod m.
-- If there is no such x return Nothing.
modInv :: Int -> Int -> Maybe Int
Line 1,125 ⟶ 1,703:
 
main :: IO ()
main = mapM_ print [2 `modInv` 4, 42 `modInv` 2017]</langsyntaxhighlight>
{{out}}
<pre>Nothing
Line 1,132 ⟶ 1,710:
=={{header|Icon}} and {{header|Unicon}}==
{{trans|C}}
<langsyntaxhighlight lang="unicon">procedure main(args)
a := integer(args[1]) | 42
b := integer(args[2]) | 2017
Line 1,147 ⟶ 1,725:
}
return if (x1 > 0) then x1 else x1+b0
end</langsyntaxhighlight>
 
{{out}}
Line 1,158 ⟶ 1,736:
Adding a coprime test:
 
<langsyntaxhighlight lang="unicon">link numbers
 
procedure main(args)
Line 1,176 ⟶ 1,754:
}
return if (x1 > 0) then x1 else x1+b0
end</langsyntaxhighlight>
 
=={{header|IS-BASIC}}==
<langsyntaxhighlight ISlang="is-BASICbasic">100 PRINT MODINV(42,2017)
120 DEF MODINV(A,B)
130 LET B=ABS(B)
Line 1,196 ⟶ 1,774:
260 LET MODINV=T
270 END IF
280 END DEF</langsyntaxhighlight>
 
=={{header|J}}==
'''Solution''':<langsyntaxhighlight lang="j"> modInv =: dyad def 'x y&|@^ <: 5 p: y'"0</langsyntaxhighlight>
'''Example''':<langsyntaxhighlight lang="j"> 42 modInv 2017
1969</langsyntaxhighlight>
'''Notes''':
 
Line 1,212 ⟶ 1,790:
=={{header|Java}}==
The <code>BigInteger</code> library has a method for this:
<langsyntaxhighlight lang="java">System.out.println(BigInteger.valueOf(42).modInverse(BigInteger.valueOf(2017)));</langsyntaxhighlight>
{{out}}
<pre>1969</pre>
Alternatively, working from first principles.
<syntaxhighlight lang="java">
public final class ModularInverse {
 
public static void main(String[] aArgs) {
System.out.println(inverseModulus(42, 2017));
}
private static Egcd extendedGCD(int aOne, int aTwo) {
if ( aOne == 0 ) {
return new Egcd(aTwo, 0, 1);
}
Egcd value = extendedGCD(aTwo % aOne, aOne);
return new Egcd(value.aG, value.aY - ( aTwo / aOne ) * value.aX, value.aX);
}
private static int inverseModulus(int aNumber, int aModulus) {
Egcd value = extendedGCD(aNumber, aModulus);
return ( value.aG == 1 ) ? ( value.aX + aModulus ) % aModulus : 0;
}
private static record Egcd(int aG, int aX, int aY) {}
 
}
</syntaxhighlight>
{{ out }}
<pre>
1969
</pre>
 
=={{header|JavaScript}}==
Using brute force.
<langsyntaxhighlight lang="javascript">var modInverse = function(a, b) {
a %= b;
for (var x = 1; x < b; x++) {
Line 1,225 ⟶ 1,832:
}
}
}</langsyntaxhighlight>
 
=={{header|jq}}==
Line 1,231 ⟶ 1,838:
'''Works with gojq, the Go implementation of jq'''
 
<langsyntaxhighlight lang="jq"># Integer division:
# If $j is 0, then an error condition is raised;
# otherwise, assuming infinite-precision integer arithmetic,
Line 1,267 ⟶ 1,874:
# Example:
42 | modInv(2017)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,278 ⟶ 1,885:
===Built-in===
Julia includes a built-in function for this:
<syntaxhighlight lang ="julia">invmod(a, b)</langsyntaxhighlight>
 
===C translation===
Line 1,284 ⟶ 1,891:
The following code works on any integer type.
To maximize performance, we ensure (via a promotion rule) that the operands are the same type (and use built-ins <code>zero(T)</code> and <code>one(T)</code> for initialization of temporary variables to ensure that they remain of the same type throughout execution).
<langsyntaxhighlight lang="julia">function modinv{T<:Integer}(a::T, b::T) where T <: Integer
b0 = b
x0, x1 = zero(T), one(T)
Line 1,294 ⟶ 1,901:
x1 < 0 ? x1 + b0 : x1
end
modinv(a::Integer, b::Integer) = modinv(promote(a,b)...)</langsyntaxhighlight>
 
{{out}}
Line 1,306 ⟶ 1,913:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
import java.math.BigInteger
Line 1,314 ⟶ 1,921:
val m = BigInteger.valueOf(2017)
println(a.modInverse(m))
}</langsyntaxhighlight>
 
{{out}}
Line 1,320 ⟶ 1,927:
1969
</pre>
 
=={{header|Lambdatalk}}==
{{trans|Phix}}
<syntaxhighlight lang="scheme">
 
{def mulinv
{def mulinv.loop
{lambda {:t :nt :r :nr}
{if {not {= :nr 0}}
then {mulinv.loop :nt
{- :t {* {floor {/ :r :nr}} :nt}}
:nr
{- :r {* {floor {/ :r :nr}} :nr}} }
else {cons :t :r} }}}
{lambda {:a :n}
{let { {:a :a} {:n :n}
{:cons {mulinv.loop 0
1
{if {< :n 0} then {- :n} else :n}
{if {< :a 0} then {- :n {% {- :a} :n}} else :a}}}
} {if {> {cdr :cons} 1}
then not invertible
else {if {< {car :cons} 0}
then {+ {car :cons} :n}
else {car :cons} }}}}}
-> mulinv
 
{mulinv 42 2017}
-> 1969
{mulinv 40 1}
-> 0
{mulinv 52 -217}
-> 96
{mulinv -486 217}
-> 121
{mulinv 40 218}
-> not invertible
 
</syntaxhighlight>
 
=={{header|m4}}==
{{trans|Mercury}}
 
Note that <code>$0</code> is the name of the macro being evaluated. Therefore, in the following, <code>_$0</code> is the name of another macro, the same as the name of the first macro, except for an underscore prepended. This is a common idiom.
 
The core of the program is <code>__inverse</code> recursively calling itself.
 
m4 is a macro-preprocessor, and so some of the following is there simply to keep things from being echoed to the output. :)
 
<syntaxhighlight lang="m4">
divert(-1)
 
# I assume non-negative arguments. The algorithm is described at
# https://en.wikipedia.org/w/index.php?title=Extended_Euclidean_algorithm&oldid=1135569411#Modular_integers
 
define(`inverse',`_$0(eval(`$1'), eval(`$2'))')
define(`_inverse',`_$0($2, 0, 1, $2, $1)')
define(`__inverse',
`dnl n = $1, t = $2, newt = $3, r = $4, newr = $5
ifelse(eval($5 != 0), 1, `$0($1, $3,
eval($2 - (($4 / $5) * $3)),
$5,eval($4 % $5))',
eval($4 > 1), 1, `no inverse',
eval($2 < 0), 1, eval($2 + $1),
$2)')
 
divert`'dnl
inverse(42, 2017)
</syntaxhighlight>
 
{{out}}
<pre>$ m4 modular-inverse-task.m4
1969</pre>
 
=={{header|MAD}}==
<syntaxhighlight lang="mad"> NORMAL MODE IS INTEGER
INTERNAL FUNCTION(AA, BB)
ENTRY TO MULINV.
A = AA
B = BB
WHENEVER B.L.0, B = -B
WHENEVER A.L.0, A = B - (-(A-A/B*B))
T = 0
NT = 1
R = B
NR = A-A/B*B
LOOP WHENEVER NR.NE.0
Q = R/NR
TMP = NT
NT = T - Q*NT
T = TMP
TMP = NR
NR = R - Q*NR
R = TMP
TRANSFER TO LOOP
END OF CONDITIONAL
WHENEVER R.G.1, FUNCTION RETURN -1
WHENEVER T.L.0, T = T+B
FUNCTION RETURN T
END OF FUNCTION
INTERNAL FUNCTION(AA, BB)
VECTOR VALUES FMT = $I5,2H, ,I5,2H: ,I5*$
ENTRY TO SHOW.
PRINT FORMAT FMT, AA, BB, MULINV.(AA, BB)
END OF FUNCTION
SHOW.(42,2017)
SHOW.(40,1)
SHOW.(52,-217)
SHOW.(-486,217)
SHOW.(40,2018)
END OF PROGRAM</syntaxhighlight>
{{out}}
<pre> 42, 2017: 1969
40, 1: 0
52, -217: 96
-486, 217: 121
40, 2018: -1</pre>
 
=={{header|Maple}}==
 
<syntaxhighlight lang="maple">
<lang Maple>
1/42 mod 2017;
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,332 ⟶ 2,058:
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
TheUse the built-in function <code>FindInstanceModularInverse</code> works well for this:
<lang Mathematica>modInv[a_, m_] :=
Block[{x,k}, x /. FindInstance[a x == 1 + k m, {x, k}, Integers]]</lang>
 
<syntaxhighlight lang="mathematica">ModularInverse[a, m]</syntaxhighlight>
Another way by using the built-in function <code>PowerMod</code> :
For example:
<lang Mathematica>PowerMod[a,-1,m]</lang>
<pre>ModularInverse[42, 2017]
For example :
<pre>modInv[42, 2017]
{1969}
PowerMod[42, -1, 2017]
1969</pre>
 
=={{header|Maxima}}==
Using built-in function inv_mod
<syntaxhighlight lang="maxima">
inv_mod(42,2017);
</syntaxhighlight>
{{out}}
<pre>
1969
</pre>
 
=={{header|Mercury}}==
{{works with|Mercury|22.01.1}}
 
<syntaxhighlight lang="mercury">
%%% -*- mode: mercury; prolog-indent-width: 2; -*-
%%%
%%% Compile with:
%%% mmc --make --use-subdirs modular_inverse_task
%%%
 
:- module modular_inverse_task.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
 
:- implementation.
:- import_module exception.
:- import_module int.
 
%% inverse(A, N, Inverse). I assume N > 0, and throw an exception if
%% it is not. The predicate fails if there is no inverse (and thus is
%% "semidet"). The algorithm is described at
%% https://en.wikipedia.org/w/index.php?title=Extended_Euclidean_algorithm&oldid=1135569411#Modular_integers
:- pred inverse(int::in, int::in, int::out) is semidet.
inverse(A, N, Inverse) :-
if (N =< 0) then throw(domain_error("inverse"))
else inverse_(N, 0, 1, N, A, Inverse).
 
:- pred inverse_(int::in, int::in, int::in, int::in, int::in,
int::out) is semidet.
inverse_(N, T, NewT, R, NewR, Inverse) :-
if (NewR \= 0)
then (Quotient = div(R, NewR), % Floor division.
inverse_(N,
NewT, T - (Quotient * NewT),
NewR, R - (Quotient * NewR),
Inverse)) % Tail recursion.
else (R =< 1, % R =< 1 FAILS if R > 1.
(if (T < 0) then Inverse = T + N else Inverse = T)).
 
main(!IO) :-
if inverse(42, 2017, Inverse)
then (print(Inverse, !IO), nl(!IO))
else (print("There is no inverse.", !IO), nl(!IO)).
 
:- end_module modular_inverse_task.
</syntaxhighlight>
 
{{out}}
<pre>$ mmc --make --use-subdirs modular_inverse_task && ./modular_inverse_task
Making Mercury/int3s/modular_inverse_task.int3
Making Mercury/ints/modular_inverse_task.int
Making Mercury/cs/modular_inverse_task.c
Making Mercury/os/modular_inverse_task.o
Making modular_inverse_task
1969
</pre>
 
=={{header|МК-61/52}}==
<syntaxhighlight lang="text">П1 П2 <-> П0 0 П5 1 П6 ИП1 1
- x=0 14 С/П ИП0 1 - /-/ x<0 50
ИП0 ИП1 / [x] П4 ИП1 П3 ИП0 ^ ИП1
/ [x] ИП1 * - П1 ИП3 П0 ИП5 П3
ИП6 ИП4 ИП5 * - П5 ИП3 П6 БП 14
ИП6 x<0 55 ИП2 + С/П</langsyntaxhighlight>
 
=={{header|Modula-2}}==
{{trans|C}}
<langsyntaxhighlight Modulalang="modula-2">MODULE ModularInverse;
FROM InOut IMPORT WriteString, WriteInt, WriteLn;
 
Line 1,396 ⟶ 2,185:
WriteLn;
END;
END ModularInverse.</langsyntaxhighlight>
{{out}}
<pre>Modular inverse
Line 1,406 ⟶ 2,195:
 
=={{header|newLISP}}==
<syntaxhighlight lang="newlisp">
<lang NewLisp>
(define (modular-multiplicative-inverse a n)
(if (< n 0)
Line 1,437 ⟶ 2,226:
 
(println (modular-multiplicative-inverse 42 2017))
</syntaxhighlight>
</lang>
 
Output:
Line 1,446 ⟶ 2,235:
=={{header|Nim}}==
{{trans|C}}
<langsyntaxhighlight lang="nim">proc modInv(a0, b0: int): int =
var (a, b, x0) = (a0, b0, 0)
result = 1
Line 1,457 ⟶ 2,246:
if result < 0: result += b0
 
echo modInv(42, 2017)</langsyntaxhighlight>
 
{{out}}
<pre>1969</pre>
 
=={{header|Oberon-2}}==
{{works with|Oxford Oberon-2 Compiler|3.3.0}}
 
<syntaxhighlight lang="oberon">
(*-*- mode: indented-text; tab-width: 2; -*-*)
 
MODULE modularInverseInOberon2;
 
IMPORT Out;
 
(* Division with a non-negative remainder. This will work no matter
how your compiler handles DIV (and mine seems not to do what the
Oberon-2 specification says). *)
PROCEDURE euclidDiv (x, y : INTEGER) : INTEGER;
VAR q : INTEGER;
BEGIN
IF 0 <= y THEN (* Do floor division. *)
IF 0 <= x THEN
q := x DIV y
ELSE
q := -((-x) DIV y);
IF (-x) MOD y # 0 THEN q := q - 1 END
END;
ELSE (* Do ceiling division. *)
IF 0 <= x THEN
q := -(x DIV (-y))
ELSE
q := ((-x) DIV (-y));
IF (-x) MOD (-y) # 0 THEN q := q + 1 END
END
END;
RETURN q
END euclidDiv;
 
(* I have added this unit test because, earlier, I posted a buggy
version of euclidDiv. *)
PROCEDURE testEuclidDiv;
VAR x, y, q, r : INTEGER;
BEGIN
FOR x := -100 TO 100 DO
FOR y := -100 TO 100 DO
IF y # 0 THEN
q := euclidDiv (x, y);
r := x - (q * y);
IF (r < 0) OR (ABS (y) <= r) THEN
(* A remainder was outside the expected range. *)
Out.String ("euclidDiv fails its test")
END
END
END
END
END testEuclidDiv;
 
PROCEDURE inverse (a, n : INTEGER) : INTEGER;
VAR t, newt : INTEGER;
VAR r, newr : INTEGER;
VAR quotient : INTEGER;
VAR tmp : INTEGER;
BEGIN
t := 0; newt := 1;
r := n; newr := a;
WHILE newr # 0 DO
quotient := euclidDiv (r, newr);
tmp := newt; newt := t - (quotient * newt); t := tmp;
tmp := newr; newr := r - (quotient * newr); r := tmp
END;
IF r > 1 THEN
t := -1
ELSIF t < 0 THEN
t := t + n
END;
RETURN t
END inverse;
 
BEGIN
testEuclidDiv;
Out.Int (inverse (42, 2017), 0);
Out.Ln
END modularInverseInOberon2.
</syntaxhighlight>
 
{{out}}
<pre>$ obc modularInverseInOberon2.Mod && ./a.out
1969
</pre>
 
=={{header|ObjectIcon}}==
{{trans|Oberon-2}}
{{trans|Mercury}}
 
<syntaxhighlight lang="objecticon">
# -*- ObjectIcon -*-
 
import exception
import io
 
procedure main ()
test_euclid_div ()
io.write (inverse (42, 2017))
end
 
procedure inverse (a, n) # FAILS if there is no inverse.
local t, newt, r, newr, quotient, tmp
 
if n <= 0 then throw ("non-positive modulus")
t := 0; newt := 1
r := n; newr := a
while newr ~= 0 do
{
quotient := euclid_div (r, newr)
tmp := newt; newt := t - (quotient * newt); t := tmp
tmp := newr; newr := r - (quotient * newr); r := tmp
}
r <= 1 | fail
return (if t < 0 then t + n else t)
end
 
procedure euclid_div (x, y)
# This kind of integer division always gives a remainder between 0
# and abs(y)-1, inclusive. Thus the remainder is always a LEAST
# RESIDUE modulo abs(y). (If y is a positive modulus, then only the
# floor division branch is used.)
return \
if 0 <= y then # Do floor division.
(if 0 <= x then x / y
else if (-x) % y = 0 then -((-x) / y)
else -((-x) / y) - 1)
else # Do ceiling division.
(if 0 <= x then -(x / (-y))
else if (-x) % (-y) = 0 then ((-x) / (-y))
else ((-x) / (-y)) + 1)
end
 
procedure test_euclid_div ()
local x, y, q, r
 
every x := -100 to 100 do
every y := -100 to 100 & y ~= 0 do
{
q := euclid_div (x, y)
r := x - (q * y)
if r < 0 | abs (y) <= r then
# A remainder was outside the expected range.
throw ("Test of euclid_div failed.")
}
end
</syntaxhighlight>
 
{{out}}
<pre>$ oiscript modular-inverse-task-OI.icn
1969</pre>
 
=={{header|OCaml}}==
 
==={{trans|C}}===
<langsyntaxhighlight lang="ocaml">let mul_inv a = function 1 -> 1 | b ->
let rec aux a b x0 x1 =
if a <= 1 then x1 else
Line 1,472 ⟶ 2,413:
in
let x = aux a b 0 1 in
if x < 0 then x + b else x</langsyntaxhighlight>
 
Testing:
Line 1,482 ⟶ 2,423:
==={{trans|Haskell}}===
 
<langsyntaxhighlight lang="ocaml">let rec gcd_ext a = function
| 0 -> (1, 0, a)
| b ->
Line 1,492 ⟶ 2,433:
match gcd_ext a m with
| i, _, 1 -> mk_pos i
| _ -> failwith "mod_inv"</langsyntaxhighlight>
 
Testing:
Line 1,504 ⟶ 2,445:
Usage : a modulus invmod
 
<langsyntaxhighlight Oforthlang="oforth">// euclid ( a b -- u v r )
// Return r = gcd(a, b) and (u, v) / r = au + bv
 
Line 1,525 ⟶ 2,466:
: invmod(a, modulus)
a modulus euclid 1 == ifFalse: [ drop drop null return ]
drop dup 0 < ifTrue: [ modulus + ] ;</langsyntaxhighlight>
 
{{out}}
Line 1,532 ⟶ 2,473:
1969
</pre>
 
=={{header|Owl Lisp}}==
{{works with|Owl Lisp|0.2.1}}
 
<syntaxhighlight lang="scheme">
(import (owl math)
(owl math extra))
 
(define (euclid-quotient x y)
(if (<= 0 y)
(cond ((<= 0 x) (quotient x y))
((zero? (remainder (negate x) y))
(negate (quotient (negate x) y)))
(else (- (negate (quotient (negate x) y)) 1)))
(cond ((<= 0 x) (negate (quotient x (negate y))))
((zero? (remainder (negate x) (negate y)))
(quotient (negate x) (negate y)))
(else (+ (quotient (negate x) (negate y)) 1)))))
 
;; A unit test of euclid-quotient.
(let repeat ((x -100)
(y -100))
(cond ((= x 101) #t)
((= y 0) (repeat x (+ y 1)))
((= y 101) (repeat (+ x 1) -100))
(else (let* ((q (euclid-quotient x y))
(r (- x (* q y))))
(cond ((< r 0) (display "negative remainder\n"))
((<= (abs y) r) (display "remainder too large\n"))
(else (repeat x (+ y 1))))))))
 
(define (inverse a n)
(let repeat ((t 0) (newt 1)
(r n) (newr a))
(cond ((not (zero? newr))
(let ((quotient (euclid-quotient r newr)))
(repeat newt (- t (* quotient newt))
newr (- r (* quotient newr)))))
((< 1 r) #f) ; The inverse does not exist.
((negative? t) (+ t n))
(else t))))
 
(display (inverse 42 2017))
(newline)
</syntaxhighlight>
 
{{out}}
<pre>$ ol modular-inverse-task-Owl.scm
1969</pre>
 
=={{header|PARI/GP}}==
<syntaxhighlight lang ="parigp">Mod(1/42,2017)</langsyntaxhighlight>
 
=={{header|Pascal}}==
<syntaxhighlight lang="pascal">
<lang Pascal>
// increments e step times until bal is greater than t
// repeats until bal = 1 (mod = 1) and returns count
Line 1,561 ⟶ 2,551:
end;
modInv := d;
end;</langsyntaxhighlight>
 
Testing:
Line 1,572 ⟶ 2,562:
=={{header|Perl}}==
Various CPAN modules can do this, such as:
<langsyntaxhighlight lang="perl">use bigint; say 42->bmodinv(2017);
# or
use Math::ModInt qw/mod/; say mod(42, 2017)->inverse->residue;
Line 1,580 ⟶ 2,570:
use Math::GMP qw/:constant/; say 42->bmodinv(2017);
# or
use ntheory qw/invmod/; say invmod(42, 2017);</langsyntaxhighlight>
or we can write our own:
<langsyntaxhighlight lang="perl">sub invmod {
my($a,$n) = @_;
my($t,$nt,$r,$nr) = (0, 1, $n, $a % $n);
Line 1,596 ⟶ 2,586:
}
 
say invmod(42,2017);</langsyntaxhighlight>
'''Notes''': Special cases to watch out for include (1) where the inverse doesn't exist, such as invmod(14,28474), which should return undef or raise an exception, not return a wrong value. (2) the high bit of a or n is set, e.g. invmod(11,2**63), (3) negative first arguments, e.g. invmod(-11,23).
The modules and code above handle these cases,
Line 1,603 ⟶ 2,593:
=={{header|Phix}}==
{{trans|C}}
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">mul_inv</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">n</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
Line 1,624 ⟶ 2,614:
<span style="color: #0000FF;">?</span><span style="color: #000000;">mul_inv</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">486</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">217</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">mul_inv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">40</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2018</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,636 ⟶ 2,626:
=={{header|PHP}}==
'''Algorithm Implementation'''
<langsyntaxhighlight lang="php"><?php
function invmod($a,$n){
if ($n < 0) $n = -$n;
Line 1,651 ⟶ 2,641:
}
printf("%d\n", invmod(42, 2017));
?></langsyntaxhighlight>
{{Out}}
<pre>1969</pre>
Line 1,657 ⟶ 2,647:
=={{header|PicoLisp}}==
{{trans|C}}
<langsyntaxhighlight PicoLisplang="picolisp">(de modinv (A B)
(let (B0 B X0 0 X1 1 Q 0 T1 0)
(while (< 1 A)
Line 1,673 ⟶ 2,663:
(modinv 42 2017) )
 
(bye)</langsyntaxhighlight>
 
=={{header|PL/I}}==
{{trans|REXX}}
<langsyntaxhighlight lang="pli">*process source attributes xref or(!);
/*--------------------------------------------------------------------
* 13.07.2015 Walter Pachl
Line 1,709 ⟶ 2,699:
Return(d);
End;
End;</langsyntaxhighlight>
{{out}}
<pre>modular inverse of 42 by 2017 ---> 1969</pre>
 
=={{header|PowerShell}}==
<langsyntaxhighlight lang="powershell">function invmod($a,$n){
if ([int]$n -lt 0) {$n = -$n}
if ([int]$a -lt 0) {$a = $n - ((-$a) % $n)}
Line 1,736 ⟶ 2,726:
}
 
invmod 42 2017</langsyntaxhighlight>
{{Out}}
<pre>PS> .\INVMOD.PS1
Line 1,743 ⟶ 2,733:
 
=={{header|Prolog}}==
<syntaxhighlight lang="prolog">
<lang Prolog>
egcd(_, 0, 1, 0) :- !.
egcd(A, B, X, Y) :-
Line 1,754 ⟶ 2,744:
A*X + B*Y =:= 1,
N is X mod B.
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,766 ⟶ 2,756:
=={{header|PureBasic}}==
Using brute force.
<langsyntaxhighlight PureBasiclang="purebasic">EnableExplicit
Declare main()
Declare.i mi(a.i, b.i)
Line 1,802 ⟶ 2,792:
If x > y - 1 : x = -1 : EndIf
ProcedureReturn x
EndProcedure</langsyntaxhighlight>
{{out}}
<pre> MODULAR-INVERSE( 42, 2017) = 1969
Line 1,811 ⟶ 2,801:
 
=={{header|Python}}==
 
===Builtin function===
Since python3.8, builtin function "pow" can be used directly to compute modular inverses by specifying an exponent of -1:
<syntaxhighlight lang="python">>>> pow(42, -1, 2017)
1969
</syntaxhighlight>
 
===Iteration and error-handling===
Implementation of this [http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Iterative_method_2 pseudocode] with [https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm#Modular_inverse this].
<langsyntaxhighlight lang="python">>>> def extended_gcd(aa, bb):
lastremainder, remainder = abs(aa), abs(bb)
x, lastx, y, lasty = 0, 1, 1, 0
Line 1,831 ⟶ 2,827:
>>> modinv(42, 2017)
1969
>>> </langsyntaxhighlight>
 
===Recursion and an option type===
Or, using functional composition as an alternative to iterative mutation, and wrapping the resulting value in an option type, to allow for the expression of computations which establish the '''absence''' of a modular inverse:
 
<langsyntaxhighlight lang="python">from functools import (reduce)
from itertools import (chain)
 
Line 1,926 ⟶ 2,922:
 
# MAIN ---
main()</langsyntaxhighlight>
{{Out}}
<pre>
Line 1,935 ⟶ 2,931:
{{trans|Forth}}
 
<langsyntaxhighlight Quackerylang="quackery"> [ dup 1 != if
[ tuck 1 0
[ swap temp put
Line 1,951 ⟶ 2,947:
nip ] is modinv ( n n --> n )
 
42 2017 modinv echo</langsyntaxhighlight>
 
{{out}}
 
<pre>1969</pre>
 
===Using Extended Euclidean Algorithm===
 
Handles negative args. Returns -1 for non-coprime args.
 
<syntaxhighlight lang="quackery"> [ dup 0 = iff
[ 2drop 1 0 ]
done
dup unrot /mod
dip swap recurse
tuck 2swap *
dip swap - ] is egcd ( n n --> n n )
 
[ dup 0 < if negate
over 0 < if
[ swap negate
over tuck mod
- swap ]
dup rot 2dup egcd
2swap 2over rot *
unrot * + 1 != iff
[ drop 2drop -1 ]
done
nip swap mod ] is modinv ( n n --> n )
 
say " 42 2017 modinv --> " 42 2017 modinv echo cr ( --> 1969 )
say " 40 1 modinv --> " 40 1 modinv echo cr ( --> 0 )
say " 52 -217 modinv --> " 52 -217 modinv echo cr ( --> 96 )
say "-486 217 modinv --> " -486 217 modinv echo cr ( --> 121 )
say " 40 2018 modinv --> " 40 2018 modinv echo cr ( --> -1 )</syntaxhighlight>
 
{{out}}
 
<pre> 42 2017 modinv --> 1969
40 1 modinv --> 0
52 -217 modinv --> 96
-486 217 modinv --> 121
40 2018 modinv --> -1
</pre>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
(require math)
(modular-inverse 42 2017)
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="racket">
1969
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line>sub inverse($n, :$modulo) {
my ($c, $d, $uc, $vc, $ud, $vd) = ($n % $modulo, $modulo, 1, 0, 0, 1);
my $q;
Line 1,979 ⟶ 3,014:
}
 
say inverse 42, :modulo(2017)</langsyntaxhighlight>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program calculates and displays the modular inverse of an integer X modulo Y.*/
parse arg x y . /*obtain two integers from the C.L. */
if x=='' | x=="," then x= 42 /*Not specified? Then use the default.*/
Line 1,998 ⟶ 3,033:
 
if $<0 then $= $ + ob /*Negative? Then add the original B. */
return $</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs of: &nbsp; &nbsp; <tt> 42 &nbsp; 2017 </tt>}}
<pre>
Line 2,005 ⟶ 3,040:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
see "42 %! 2017 = " + multInv(42, 2017) + nl
 
Line 2,024 ⟶ 3,059:
if multInv < 0 multInv = multInv + b0 ok
return multInv
</syntaxhighlight>
</lang>
Output:
<pre>
42 %! 2017 = 1969
</pre>
 
=={{header|RPL}}==
Using complex numbers allows to ‘parallelize’ calculations and keeps the stack depth low: never more than 4 levels despite the simultaneous use of 6 variables: r, r’, u, u’, q - and b for the final touch.
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
DUP ROT 1 R→C ROT 0 R→C
'''WHILE''' DUP RE '''REPEAT'''
OVER RE OVER RE / FLOOR
OVER * NEG ROT +
'''END'''
DROP C→R ROT MOD
SWAP 1 == SWAP 0 IFTE
≫ ‘'''MODINV'''’ STO
|
'''MODINV''' ''( a b -- x )'' with ax = 1 mod b
3: b 2: (r,u)←(a,1) 1:(r',u')←(b,0)
While r' ≠ 0
q ← r // r'
(r - q*r', u - q*u')
Forget (r',u') and calculate u mod b
Test r and return zero if a and b are not co-prime
|}
{{in}}
<pre>
123 456 MODINV
42 2017 MODINV
</pre>
{{out}}
<pre>
2: 1969
1: 0
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">#based on pseudo code from http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Iterative_method_2 and from translating the python implementation.
def extended_gcd(a, b)
last_remainder, remainder = a.abs, b.abs
Line 2,050 ⟶ 3,124:
end
x % et
end</langsyntaxhighlight>
<pre>
> invmod(42,2017)
Line 2,056 ⟶ 3,130:
 
Simplified equivalent implementation
<langsyntaxhighlight lang="ruby">
def modinv(a, m) # compute a^-1 mod m if possible
raise "NO INVERSE - #{a} and #{m} not coprime" unless a.gcd(m) == 1
Line 2,069 ⟶ 3,143:
inv
end
</syntaxhighlight>
</lang>
<pre>
> modinv(42,2017)
=> 1969
</pre>
The OpenSSL module has modular inverse built in:
<syntaxhighlight lang="ruby">require 'openssl'
p OpenSSL::BN.new(42).mod_inverse(2017).to_i</syntaxhighlight>
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">print multInv(42, 2017)
end
 
Line 2,094 ⟶ 3,171:
if multInv < 0 then multInv = multInv + b0
[endFun]
end function</langsyntaxhighlight>
 
{{out}}
Line 2,102 ⟶ 3,179:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">fn mod_inv(a: isize, module: isize) -> isize {
let mut mn = (module, a);
let mut xy = (0, 1);
Line 2,119 ⟶ 3,196:
fn main() {
println!("{}", mod_inv(42, 2017))
}</langsyntaxhighlight>
 
{{out}}
Line 2,127 ⟶ 3,204:
 
Alternative implementation
<langsyntaxhighlight lang="rust">
fn modinv(a0: isize, m0: isize) -> isize {
if m0 == 1 { return 1 }
Line 2,146 ⟶ 3,223:
fn main() {
println!("{}", modinv(42, 2017))
}</langsyntaxhighlight>
 
{{out}}
Line 2,155 ⟶ 3,232:
=={{header|Scala}}==
Based on the ''Handbook of Applied Cryptography'', Chapter 2. See http://cacr.uwaterloo.ca/hac/ .
<langsyntaxhighlight lang="scala">
def gcdExt(u: Int, v: Int): (Int, Int, Int) = {
@tailrec
Line 2,170 ⟶ 3,247:
val (i, j, g) = gcdExt(a, m)
if (g == 1) Option(if (i < 0) i + m else i) else Option.empty
}</langsyntaxhighlight>
 
Translated from C++ (on this page)
<langsyntaxhighlight lang="scala">
def modInv(a: Int, m: Int, x:Int = 1, y:Int = 0) : Int = if (m == 0) x else modInv(m, a%m, y, x - y*(a/m))
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,192 ⟶ 3,269:
If a and b are not coprime (gcd(a, b) <> 1) the exception RANGE_ERROR is raised.
 
<langsyntaxhighlight lang="seed7">const func bigInteger: modInverse (in var bigInteger: a,
in var bigInteger: b) is func
result
Line 2,234 ⟶ 3,311:
raise RANGE_ERROR;
end if;
end func;</langsyntaxhighlight>
 
Original source: [http://seed7.sourceforge.net/algorith/math.htm#modInverse]
Line 2,240 ⟶ 3,317:
=={{header|Sidef}}==
Built-in:
<syntaxhighlight lang ="ruby">say 42.modinv(2017)</langsyntaxhighlight>
 
Algorithm implementation:
<langsyntaxhighlight lang="ruby">func invmod(a, n) {
var (t, nt, r, nr) = (0, 1, n, a % n)
while (nr != 0) {
Line 2,255 ⟶ 3,332:
}
 
say invmod(42, 2017)</langsyntaxhighlight>
{{out}}
<pre>
Line 2,263 ⟶ 3,340:
=={{header|Swift}}==
 
<langsyntaxhighlight lang="swift">extension BinaryInteger {
@inlinable
public func modInv(_ mod: Self) -> Self {
Line 2,282 ⟶ 3,359:
}
 
print(42.modInv(2017))</langsyntaxhighlight>
 
{{out}}
Line 2,290 ⟶ 3,367:
=={{header|Tcl}}==
{{trans|Haskell}}
<langsyntaxhighlight lang="tcl">proc gcdExt {a b} {
if {$b == 0} {
return [list 1 0 $a]
Line 2,306 ⟶ 3,383:
while {$i < 0} {incr i $m}
return $i
}</langsyntaxhighlight>
Demonstrating
<langsyntaxhighlight lang="tcl">puts "42 %! 2017 = [modInv 42 2017]"
catch {
puts "2 %! 4 = [modInv 2 4]"
} msg; puts $msg</langsyntaxhighlight>
{{out}}
<pre>
Line 2,320 ⟶ 3,397:
=={{header|Tiny BASIC}}==
2017 causes integer overflow, so I'll do the inverse of 42 modulo 331 instead.
<langsyntaxhighlight lang="tinybasic">
PRINT "Modular inverse."
PRINT "What is the modulus?"
Line 2,338 ⟶ 3,415:
LET B = B - M
GOTO 30
</syntaxhighlight>
</lang>
{{out}}
<pre>Modular inverse.
Line 2,350 ⟶ 3,427:
Another version:
{{trans|GW-BASIC}}
<langsyntaxhighlight lang="tinybasic">
REM Modular inverse
LET E=42
Line 2,378 ⟶ 3,455:
130 LET M=D
RETURN
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,385 ⟶ 3,462:
 
=={{header|tsql}}==
<langsyntaxhighlight lang="tsql">;WITH Iterate(N,A,B,X0,X1)
AS (
SELECT
Line 2,418 ⟶ 3,495:
)
SELECT *
FROM ModularInverse</langsyntaxhighlight>
 
== {{header|TypeScript}} ==
{{trans|Pascal}}
<syntaxhighlight lang="javascript">
// Modular inverse
 
function modInv(e: number, t: number): number {
var d = 0;
if (e < t) {
var count = 1;
var bal = e;
do {
var step = Math.floor((t - bal) / e) + 1;
bal += step * e;
count += step;
bal -= t;
} while (bal != 1);
d = count;
}
return d;
}
 
console.log(`${modInv(42, 2017)}`); // 1969
</syntaxhighlight>
{{out}}
<pre>
1969
</pre>
 
=={{header|uBasic/4tH}}==
{{trans|C}}
<syntaxhighlight lang="text">Print FUNC(_MulInv(42, 2017))
End
 
Line 2,446 ⟶ 3,551:
 
If g@ < 0 Then g@ = g@ + c@
Return (g@)</langsyntaxhighlight>
{{trans|Perl}}
<syntaxhighlight lang="text">Print FUNC(_mul_inv(42, 2017))
Print FUNC(_mul_inv(40, 1))
Print FUNC(_mul_inv(52, -217))
Line 2,471 ⟶ 3,576:
If (e@ > 1) Return (-1) ' No inverse'
If (c@ < 0) c@ = c@ + b@
Return (c@)</langsyntaxhighlight>
{{out}}
<pre>1969
Line 2,485 ⟶ 3,590:
{{works with|Korn Shell}}
{{works with|Zsh}}
{{trans|PowerShell}}<langsyntaxhighlight lang="sh">function invmod {
typeset -i a=$1 n=$2
if (( n < 0 )); then (( n = -n )); fi
Line 2,508 ⟶ 3,613:
}
 
invmod 42 2017</langsyntaxhighlight>
 
{{Out}}
Line 2,514 ⟶ 3,619:
 
=={{header|VBA}}==
{{trans|Phix}}<langsyntaxhighlight lang="vb">
Private Function mul_inv(a As Long, n As Long) As Variant
If n < 0 Then n = -n
Line 2,545 ⟶ 3,650:
Debug.Print mul_inv(-486, 217)
Debug.Print mul_inv(40, 2018)
End Sub</langsyntaxhighlight>{{out}}
<pre> 1969
0
Line 2,551 ⟶ 3,656:
121
a is not invertible</pre>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="Zig">
fn main() {
println("42 %! 2017 = ${mult_inv(42, 2017)}")
}
 
fn mult_inv(aa int, bb int) int {
mut a, mut b := aa, bb
mut x0, mut t := 0, 0
mut b0 := b
mut x1 := 1
if b == 1 {return 1}
for a > 1 {
q := a / b
t = b
b = a % b
a = t
t = x0
x0 = x1 - q * x0
x1 = t
}
if x1 < 0 {x1 += b0}
return x1
}
</syntaxhighlight>
 
{{out}}
<pre>
42 %! 2017 = 1969
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-big}}
<langsyntaxhighlight ecmascriptlang="wren">import "./big" for BigInt
 
var a = BigInt.new(42)
var b = BigInt.new(2017)
System.print(a.modInv(b))</langsyntaxhighlight>
 
{{out}}
Line 2,566 ⟶ 3,702:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">code IntOut=11, Text=12;
int X;
def A=42, M=2017;
Line 2,572 ⟶ 3,708:
if rem(A*X/M) = 1 then [IntOut(0, X); exit];
Text(0, "Does not exist");
]</langsyntaxhighlight>
{{out}}
<pre>
Line 2,580 ⟶ 3,716:
=={{header|zkl}}==
{{trans|Haskell}}
<langsyntaxhighlight lang="zkl">fcn gcdExt(a,b){
if(b==0) return(1,0,a);
q,r:=a.divr(b); s,t,g:=gcdExt(b,r); return(t,s-q*t,g);
}
fcn modInv(a,m){i,_,g:=gcdExt(a,m); if(g==1) {if(i<0)i+m} else Void}</langsyntaxhighlight>
divr(a,b) is [integer] (a/b,remainder)
{{out}}
9,476

edits