Polynomial long division: Difference between revisions

Undo revision 361341 by Peak (talk)
(Undo revision 361341 by Peak (talk))
 
(36 intermediate revisions by 20 users not shown)
Line 28:
* Error handling (for allocations or for wrong inputs) is not mandatory.
* Conventions can be different; in particular, note that if the first coefficient in the vector is the highest power of x for the polynomial represented by the vector, then the algorithm becomes simpler.
 
 
'''Example for clarification'''
Line 87 ⟶ 88:
q: -27 -9 1 → x<sup>2</sup> - 9x - 27
r: -123 0 0 → -123
 
 
;Related task:
:* &nbsp; [[Polynomial derivative]]
 
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F degree(&poly)
L !poly.empty & poly.last == 0
poly.pop()
R poly.len - 1
 
F poly_div(&n, &D)
V dD = degree(&D)
V dN = degree(&n)
I dD < 0
exit(1)
[Float] q
I dN >= dD
q = [0.0] * dN
L dN >= dD
V d = [0.0] * (dN - dD) [+] D
V mult = n.last / Float(d.last)
q[dN - dD] = mult
d = d.map(coeff -> coeff * @mult)
n = zip(n, d).map((coeffN, coeffd) -> coeffN - coeffd)
dN = degree(&n)
E
q = [0.0]
R (q, n)
 
print(‘POLYNOMIAL LONG DIVISION’)
V n = [-42.0, 0.0, -12.0, 1.0]
V D = [-3.0, 1.0, 0.0, 0.0]
print(‘ #. / #. =’.format(n, D), end' ‘ ’)
V (q, r) = poly_div(&n, &D)
print(‘ #. remainder #.’.format(q, r))</syntaxhighlight>
 
{{out}}
<pre>
POLYNOMIAL LONG DIVISION
[-42, 0, -12, 1] / [-3, 1, 0, 0] = [-27, -9, 1] remainder [-123]
</pre>
 
=={{header|Ada}}==
long_division.adb:
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Long_Division is
Line 199 ⟶ 245:
Put ("Q: "); Output (Test_Q);
Put ("R: "); Output (Test_R);
end Long_Division;</langsyntaxhighlight>
 
output:
Line 208 ⟶ 254:
Q: x^2 + -9*x + -27
R: -123</pre>
 
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">
BEGIN # polynomial division #
# in this polynomials are represented by []INT items where #
# the coefficients are in order of increasing powers, i.e., #
# element 0 = coefficient of x^0, element 1 = coefficient of #
# x^1, etc. #
 
# returns the degree of the polynomial p, the highest index of #
# p where the element is non-zero or - max int if all #
# elements of p are 0 #
OP DEGREE = ( []INT p )INT:
BEGIN
INT result := - max int;
FOR i FROM LWB p TO UPB p DO
IF p[ i ] /= 0 THEN result := i FI
OD;
result
END # DEGREE # ;
 
MODE POLYNOMIALDIVISIONRESULT = STRUCT( FLEX[ 1 : 0 ]INT q, r );
 
# in-place multiplication of the elements of a by b returns a #
OP *:= = ( REF[]INT a, INT b )REF[]INT:
BEGIN
FOR i FROM LWB a TO UPB a DO
a[ i ] *:= b
OD;
a
END # *:= # ;
# subtracts the corresponding elements of b from those of a, #
# a and b must have the same bounds - returns a #
OP -:= = ( REF[]INT a, []INT b )REF[]INT:
BEGIN
FOR i FROM LWB a TO UPB a DO
a[ i ] -:= b[ i ]
OD;
a
END # -:= # ;
# returns the polynomial a right-shifted by shift, the bounds #
# are unchanged, so high order elements are lost #
OP SHR = ( []INT a, INT shift )[]INT:
BEGIN
INT da = DEGREE a;
[ LWB a : UPB a ]INT result;
FOR i FROM LWB result TO shift - ( LWB result + 1 ) DO result[ i ] := 0 OD;
FOR i FROM shift - LWB result TO UPB result DO result[ i ] := a[ i - shift ] OD;
result
END # SHR # ;
 
# polynomial long disivion of n in by d in, returns q and r #
OP / = ( []INT n in, d in )POLYNOMIALDIVISIONRESULT:
IF DEGREE d < 0 THEN
print( ( "polynomial division by polynomial with negative degree", newline ) );
stop
ELSE
[ LWB d in : UPB d in ]INT d := d in;
[ LWB n in : UPB n in ]INT n := n in;
[ LWB n in : UPB n in ]INT q; FOR i FROM LWB q TO UPB q DO q[ i ] := 0 OD;
INT dd in = DEGREE d in;
WHILE DEGREE n >= dd in DO
d := d in SHR ( DEGREE n - dd in );
q[ DEGREE n - dd in ] := n[ DEGREE n ] OVER d[ DEGREE d ];
# DEGREE d is now DEGREE n #
d *:= q[ DEGREE n - dd in ];
n -:= d
OD;
( q, n )
FI # / # ;
 
# displays the polynomial p #
OP SHOWPOLYNOMIAL = ( []INT p )VOID:
BEGIN
BOOL first := TRUE;
FOR i FROM UPB p BY - 1 TO LWB p DO
IF INT e = p[ i ];
e /= 0
THEN
print( ( IF e < 0 AND first THEN "-"
ELIF e < 0 THEN " - "
ELIF first THEN ""
ELSE " + "
FI
, IF ABS e = 1 THEN "" ELSE whole( ABS e, 0 ) FI
)
);
IF i > 0 THEN
print( ( "x" ) );
IF i > 1 THEN print( ( "^", whole( i, 0 ) ) ) FI
FI;
first := FALSE
FI
OD;
IF first THEN
# degree is negative #
print( ( "(negative degree)" ) )
FI
END # SHOWPOLYNOMIAL # ;
 
[]INT n = ( []INT( -42, 0, -12, 1 ) )[ AT 0 ];
[]INT d = ( []INT( -3, 1, 0, 0 ) )[ AT 0 ];
 
POLYNOMIALDIVISIONRESULT qr = n / d;
 
SHOWPOLYNOMIAL n; print( ( " divided by " ) ); SHOWPOLYNOMIAL d;
print( ( newline, " -> Q: " ) ); SHOWPOLYNOMIAL q OF qr;
print( ( newline, " R: " ) ); SHOWPOLYNOMIAL r OF qr
 
END
</syntaxhighlight>
{{out}}
<pre>
x^3 - 12x^2 - 42 divided by x - 3
-> Q: x^2 - 9x - 27
R: -123
</pre>
 
=={{header|APL}}==
<langsyntaxhighlight APLlang="apl">div←{
{
q r d←⍵
Line 217 ⟶ 381:
} ⍬ ⍺ ⍵
}
</syntaxhighlight>
</lang>
{{out}}
<pre> N←¯42 0 ¯12 1
Line 227 ⟶ 391:
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> DIM N%(3) : N%() = -42, 0, -12, 1
DIM D%(3) : D%() = -3, 1, 0, 0
DIM q%(3), r%(3)
Line 270 ⟶ 434:
IF n%<0 THEN = " - " + STR$(-n%)
IF n%=1 THEN = " + "
= " + " + STR$(n%)</langsyntaxhighlight>
'''Output:'''
<pre>
Line 281 ⟶ 445:
 
{{libheader|GNU Scientific Library}}
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
Line 387 ⟶ 551:
 
return r;
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="c">int main()
{
int i;
Line 411 ⟶ 575:
 
return 0;
}</langsyntaxhighlight>
 
===Another version===
Without outside libs, for clarity. Note that polys are stored and show with zero-degree term first:<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
Line 517 ⟶ 681:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
 
=={{header|C++}}==
<lang cpp>
#include <iostream>
#include <math.h>
 
using namespace std;
 
// does: prints all members of vector
// input: c - ASCII char with the name of the vector
// d - degree of vector
// A - pointer to vector
void Print(char c, int d, double* A) {
int i;
 
for (i=0; i < d+1; i++)
cout << c << "[" << i << "]= " << A[i] << endl;
cout << "Degree of " << c << ": " << d << endl << endl;
}</lang>
 
<lang cpp>int main() {
double *N,*D,*d,*q,*r; // vectors - N / D = q N % D = r
int dN, dD, dd, dq, dr; // degrees of vectors
int i; // iterators
 
// setting the degrees of vectors
cout << "Enter the degree of N:";
cin >> dN;
cout << "Enter the degree of D:";
cin >> dD;
dq = dN-dD;
dr = dN-dD;
 
 
// allocation and initialization of vectors
N=new double [dN+1];
cout << "Enter the coefficients of N:"<<endl;
for ( i = 0; i < dN+1; i++ ) {
cout << "N[" << i << "]= " << endl;
cin >> N[i];
}
 
D=new double [dN+1];
cout << "Enter the coefficients of D:"<<endl;
for ( i = 0; i < dD+1; i++ ) {
cout << "D[" << i << "]= " << endl;
cin >> D[i];
}
 
d=new double [dN+1];
for( i = dD+1 ; i < dN+1; i++ ) {
D[i] = 0;
}
 
q=new double [dq+1];
for( i = 0 ; i < dq + 1 ; i++ ) {
q[i] = 0;
}
 
r=new double [dr+1];
for( i = 0 ; i < dr + 1 ; i++ ) {
r[i] = 0;
}
 
if( dD < 0) {
cout << "Degree of D is less than zero. Error!";
}
 
cout << "-- Procedure --" << endl << endl;
if( dN >= dD ) {
while(dN >= dD) {
// d equals D shifted right
for( i = 0 ; i < dN + 1 ; i++ ) {
d[i] = 0;
}
for( i = 0 ; i < dD + 1 ; i++ ) {
d[i+dN-dD] = D[i];
}
dd = dN;
 
Print( 'd', dd, d );
 
// calculating one element of q
q[dN-dD] = N[dN]/d[dd];
 
Print( 'q', dq, q );
 
// d equals d * q[dN-dD]
for( i = 0 ; i < dq + 1 ; i++ ) {
d[i] = d[i] * q[dN-dD];
}
 
Print( 'd', dd, d );
 
// N equals N - d
for( i = 0 ; i < dN + 1 ; i++ ) {
N[i] = N[i] - d[i];
}
dN--;
 
Print( 'N', dN, N );
cout << "-----------------------" << endl << endl;
 
}
 
}
 
// r equals N
for( i = 0 ; i < dN + 1 ; i++ ) {
r[i] = N[i];
}
dr = dN;
 
cout << "=========================" << endl << endl;
cout << "-- Result --" << endl << endl;
 
Print( 'q', dq, q );
Print( 'r', dr, r );
 
// dealocation
delete [] N;
delete [] D;
delete [] d;
delete [] q;
delete [] r;
}</lang>
 
=={{header|C#|C sharp}}==
{{trans|Java}}
<langsyntaxhighlight lang="csharp">using System;
 
namespace PolynomialLongDivision {
Line 770 ⟶ 807:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>Numerator : x^3 - 12.0x^2 - 42.0
Line 777 ⟶ 814:
Quotient : x^2 - 9.0x - 27.0
Remainder : -123.0</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">
#include <iostream>
#include <iterator>
#include <vector>
 
using namespace std;
typedef vector<double> Poly;
 
// does: prints all members of vector
// input: c - ASCII char with the name of the vector
// A - reference to polynomial (vector)
void Print(char name, const Poly &A) {
cout << name << "(" << A.size()-1 << ") = [ ";
copy(A.begin(), A.end(), ostream_iterator<decltype(A[0])>(cout, " "));
cout << "]\n";
}
 
int main() {
Poly N, D, d, q, r; // vectors - N / D == q && N % D == r
size_t dN, dD, dd, dq, dr; // degrees of vectors
size_t i; // loop counter
 
// setting the degrees of vectors
cout << "Enter the degree of N: ";
cin >> dN;
cout << "Enter the degree of D: ";
cin >> dD;
dq = dN-dD;
dr = dN-dD;
 
if( dD < 1 || dN < 1 ) {
cerr << "Error: degree of D and N must be positive.\n";
return 1;
}
 
// allocation and initialization of vectors
N.resize(dN+1);
cout << "Enter the coefficients of N:"<<endl;
for ( i = 0; i <= dN; i++ ) {
cout << "N[" << i << "]= ";
cin >> N[i];
}
 
D.resize(dN+1);
cout << "Enter the coefficients of D:"<<endl;
for ( i = 0; i <= dD; i++ ) {
cout << "D[" << i << "]= ";
cin >> D[i];
}
 
d.resize(dN+1);
q.resize(dq+1);
r.resize(dr+1);
 
cout << "-- Procedure --" << endl << endl;
if( dN >= dD ) {
while(dN >= dD) {
// d equals D shifted right
d.assign(d.size(), 0);
 
for( i = 0 ; i <= dD ; i++ )
d[i+dN-dD] = D[i];
dd = dN;
 
Print( 'd', d );
 
// calculating one element of q
q[dN-dD] = N[dN]/d[dd];
 
Print( 'q', q );
 
// d equals d * q[dN-dD]
for( i = 0 ; i < dq + 1 ; i++ )
d[i] = d[i] * q[dN-dD];
 
Print( 'd', d );
 
// N equals N - d
for( i = 0 ; i < dN + 1 ; i++ )
N[i] = N[i] - d[i];
dN--;
 
Print( 'N', N );
cout << "-----------------------" << endl << endl;
 
}
}
 
// r equals N
for( i = 0 ; i <= dN ; i++ )
r[i] = N[i];
 
cout << "=========================" << endl << endl;
cout << "-- Result --" << endl << endl;
 
Print( 'q', q );
Print( 'r', r );
}
 
</syntaxhighlight>
 
=={{header|Clojure}}==
Line 784 ⟶ 923:
Since this algorithm is much more efficient when the input is in [https://en.wikipedia.org/wiki/Monomial_order#Graded_reverse_lexicographic_order graded reverse lexicographic (grevlex) order] a comparator is included to be used with Clojure's sorted-map&mdash;<code>(into (sorted-map-by grevlex) ...)</code>&mdash;as well as necessary functions to compute polynomial multiplication, monomial complements, and S-polynomials.
 
<langsyntaxhighlight lang="clojure">(defn grevlex [term1 term2]
(let [grade1 (reduce +' term1)
grade2 (reduce +' term2)
Line 878 ⟶ 1,017:
(is (= (divide {[1 1] 2, [1 0] 10, [0 1] 3, [0 0] 15}
{[1 0] 2, [0 0] 3})
'({[0 1] 1, [0 0] 5} {}))))</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
Line 884 ⟶ 1,023:
Polynomials are represented as lists of degree/coefficient pairs ordered by degree (highest degree first), and pairs with zero coefficients can be omitted. <code>Multiply</code> and <code>divide</code> perform long multiplication and long division, respectively. <code>multiply</code> returns one value, the product, and <code>divide</code> returns two, the quotient and the remainder.
 
<langsyntaxhighlight lang="lisp">(defun add (p1 p2)
(do ((sum '())) ((and (endp p1) (endp p2)) (nreverse sum))
(let ((pd1 (if (endp p1) -1 (caar p1)))
Line 924 ⟶ 1,063:
(if (endp quotient) (return (values sum remainder))
(setf dividend remainder
sum (add quotient sum)))))))</langsyntaxhighlight>
 
The [[wp:Polynomial_long_division#Example|wikipedia example]]:
 
<langsyntaxhighlight lang="lisp">> (divide '((3 . 1) (2 . -12) (0 . -42)) ; x^3 - 12x^2 - 42
'((1 . 1) (0 . -3))) ; x - 3
((2 . 1) (1 . -9) (0 . -27)) ; x^2 - 9x - 27
((0 . -123)) ; -123</langsyntaxhighlight>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.range, std.algorithm, std.typecons, std.conv;
 
Tuple!(double[], double[]) polyDiv(in double[] inN, in double[] inD)
Line 975 ⟶ 1,114:
immutable D = [-3.0, 1.0, 0.0, 0.0];
writefln("%s / %s = %s remainder %s", N, D, polyDiv(N, D)[]);
}</langsyntaxhighlight>
{{out}}
<pre>[-42, 0, -12, 1] / [-3, 1, 0, 0] = [-27, -9, 1] remainder [-123]</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|C#}}
<syntaxhighlight lang="delphi">
program Polynomial_long_division;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
type
PPolySolution = ^TPolySolution;
 
TPolynomio = record
private
class function Degree(p: TPolynomio): Integer; static;
class function ShiftRight(p: TPolynomio; places: Integer): TPolynomio; static;
class function PolyMultiply(p: TPolynomio; m: double): TPolynomio; static;
class function PolySubtract(p, s: TPolynomio): TPolynomio; static;
class function PolyLongDiv(n, d: TPolynomio): PPolySolution; static;
function GetSize: Integer;
public
value: TArray<Double>;
class operator RightShift(p: TPolynomio; b: Integer): TPolynomio;
class operator Multiply(p: TPolynomio; m: double): TPolynomio;
class operator Subtract(p, s: TPolynomio): TPolynomio;
class operator Divide(p, s: TPolynomio): PPolySolution;
class operator Implicit(a: TArray<Double>): TPolynomio;
class operator Implicit(a: TPolynomio): string;
procedure Assign(other: TPolynomio); overload;
procedure Assign(other: TArray<Double>); overload;
property Size: Integer read GetSize;
function ToString: string;
end;
 
TPolySolution = record
Quotient, Remainder: TPolynomio;
constructor Create(q, r: TPolynomio);
end;
 
{ TPolynomio }
 
procedure TPolynomio.Assign(other: TPolynomio);
begin
Assign(other.value);
end;
 
procedure TPolynomio.Assign(other: TArray<Double>);
begin
SetLength(value, length(other));
for var i := 0 to High(other) do
value[i] := other[i];
end;
 
class function TPolynomio.Degree(p: TPolynomio): Integer;
begin
var len := high(p.value);
 
for var i := len downto 0 do
begin
if p.value[i] <> 0.0 then
exit(i);
end;
Result := -1;
end;
 
class operator TPolynomio.Divide(p, s: TPolynomio): PPolySolution;
begin
Result := PolyLongDiv(p, s);
end;
 
function TPolynomio.GetSize: Integer;
begin
Result := Length(value);
end;
 
class operator TPolynomio.Implicit(a: TPolynomio): string;
begin
Result := a.toString;
end;
 
class operator TPolynomio.Implicit(a: TArray<Double>): TPolynomio;
begin
Result.Assign(a);
end;
 
class operator TPolynomio.Multiply(p: TPolynomio; m: double): TPolynomio;
begin
Result := TPolynomio.PolyMultiply(p, m);
end;
 
class function TPolynomio.PolyLongDiv(n, d: TPolynomio): PPolySolution;
var
Solution: TPolySolution;
begin
if length(n.value) <> Length(d.value) then
raise Exception.Create('Numerator and denominator vectors must have the same size');
 
var nd := Degree(n);
var dd := Degree(d);
 
if dd < 0 then
raise Exception.Create('Divisor must have at least one one-zero coefficient');
 
if nd < dd then
raise Exception.Create('The degree of the divisor cannot exceed that of the numerator');
 
var n2, q: TPolynomio;
n2.Assign(n);
SetLength(q.value, length(n.value));
 
while nd >= dd do
begin
var d2 := d shr (nd - dd);
q.value[nd - dd] := n2.value[nd] / d2.value[nd];
d2 := d2 * q.value[nd - dd];
n2 := n2 - d2;
nd := Degree(n2);
end;
new(Result);
Result^.Create(q, n2);
end;
 
class function TPolynomio.PolyMultiply(p: TPolynomio; m: double): TPolynomio;
begin
Result.Assign(p);
for var i := 0 to High(p.value) do
Result.value[i] := p.value[i] * m;
end;
 
class operator TPolynomio.RightShift(p: TPolynomio; b: Integer): TPolynomio;
begin
Result := TPolynomio.ShiftRight(p, b);
end;
 
class function TPolynomio.ShiftRight(p: TPolynomio; places: Integer): TPolynomio;
begin
Result.Assign(p);
if places <= 0 then
exit;
 
var pd := Degree(p);
 
Result.Assign(p);
for var i := pd downto 0 do
begin
Result.value[i + places] := Result.value[i];
Result.value[i] := 0.0;
end;
end;
 
class operator TPolynomio.Subtract(p, s: TPolynomio): TPolynomio;
begin
Result := TPolynomio.PolySubtract(p, s);
end;
 
class function TPolynomio.PolySubtract(p, s: TPolynomio): TPolynomio;
begin
Result.Assign(p);
for var i := 0 to High(p.value) do
Result.value[i] := p.value[i] - s.value[i];
end;
 
function TPolynomio.ToString: string;
begin
Result := '';
var pd := Degree(self);
for var i := pd downto 0 do
begin
var coeff := value[i];
if coeff = 0.0 then
Continue;
if coeff = 1.0 then
begin
if i < pd then
Result := Result + ' + ';
end
else
begin
if coeff = -1 then
begin
if i < pd then
Result := Result + ' - '
else
Result := Result + '-';
end
else
begin
if coeff < 0.0 then
begin
if i < pd then
Result := Result + format(' - %.1f', [-coeff])
else
Result := Result + format('%.1f', [coeff]);
end
else
begin
if i < pd then
Result := Result + format(' + %.1f', [coeff])
else
Result := Result + format('%.1f', [coeff]);
end;
end;
end;
if i > 1 then
Result := Result + 'x^' + i.tostring
else if i = 1 then
Result := Result + 'x';
end;
end;
 
{ TPolySolution }
 
constructor TPolySolution.Create(q, r: TPolynomio);
begin
Quotient.Assign(q);
Remainder.Assign(r);
end;
 
// Just for force implicitty string conversion
procedure Writeln(s: string);
begin
System.Writeln(s);
end;
 
var
n, d: TPolynomio;
Solution: PPolySolution;
 
begin
n := [-42.0, 0.0, -12.0, 1.0];
d := [-3.0, 1.0, 0.0, 0.0];
 
Write('Numerator : ');
Writeln(n);
Write('Denominator : ');
Writeln(d);
Writeln('-------------------------------------');
Solution := n / d;
Write('Quotient : ');
Writeln(Solution^.Quotient);
Write('Remainder : ');
Writeln(Solution^.Remainder);
FreeMem(Solution, sizeof(TPolySolution));
Readln;
end.</syntaxhighlight>
 
=={{header|E}}==
Line 1,080 ⟶ 1,466:
}</pre>
 
<langsyntaxhighlight lang="e">def n := makePolynomial([-42, 0, -12, 1])
def d := makePolynomial([-3, 1])
println("Numerator: ", n)
Line 1,086 ⟶ 1,472:
def [q, r] := n.quotRem(d, stdout)
println("Quotient: ", q)
println("Remainder: ", r)</langsyntaxhighlight>
 
Output:
Line 1,106 ⟶ 1,492:
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule Polynomial do
def division(_, []), do: raise ArgumentError, "denominator is zero"
def division(_, [0]), do: raise ArgumentError, "denominator is zero"
Line 1,136 ⟶ 1,522:
{q, r} = Polynomial.division(f, g)
IO.puts "#{inspect f} / #{inspect g} => #{inspect q} remainder #{inspect r}"
end)</langsyntaxhighlight>
 
{{out}}
Line 1,144 ⟶ 1,530:
[1, 3, 2] / [1, 1] => [1.0, 2.0] remainder [0.0]
[1, -4, 6, 5, 3] / [1, 2, 1] => [1.0, -6.0, 17.0] remainder [-23.0, -14.0]
</pre>
 
=={{header|F_Sharp|F#}}==
{{trans|Ocaml}}
<syntaxhighlight lang="fsharp">
let rec shift n l = if n <= 0 then l else shift (n-1) (l @ [0.0])
let rec pad n l = if n <= 0 then l else pad (n-1) (0.0 :: l)
let rec norm = function | 0.0 :: tl -> norm tl | x -> x
let deg l = List.length (norm l) - 1
let zip op p q =
let d = (List.length p) - (List.length q) in
List.map2 op (pad (-d) p) (pad d q)
 
let polydiv f g =
let rec aux f s q =
let ddif = (deg f) - (deg s) in
if ddif < 0 then (q, f) else
let k = (List.head f) / (List.head s) in
let ks = List.map ((*) k) (shift ddif s) in
let q' = zip (+) q (shift ddif [k])
let f' = norm (List.tail (zip (-) f ks)) in
aux f' s q' in
aux (norm f) (norm g) []
 
let str_poly l =
let term v p = match (v, p) with
| ( _, 0) -> string v
| (1.0, 1) -> "x"
| ( _, 1) -> (string v) + "*x"
| (1.0, _) -> "x^" + (string p)
| _ -> (string v) + "*x^" + (string p) in
let rec terms = function
| [] -> []
| h :: t ->
if h = 0.0 then (terms t) else (term h (List.length t)) :: (terms t) in
String.concat " + " (terms l)
 
let _ =
let f,g = [1.0; -4.0; 6.0; 5.0; 3.0], [1.0; 2.0; 1.0] in
let q, r = polydiv f g in
Printf.printf
" (%s) div (%s)\ngives\nquotient:\t(%s)\nremainder:\t(%s)\n"
(str_poly f) (str_poly g) (str_poly q) (str_poly r)
</syntaxhighlight>
{{out}}
<pre>
(x^4 + -4*x^3 + 6*x^2 + 5*x + 3) div (x^2 + 2*x + 1)
gives
quotient: (x^2 + -6*x + 17)
remainder: (-23*x + -14)
</pre>
=={{header|Factor}}==
<syntaxhighlight lang="factor">USE: math.polynomials
 
{ -42 0 -12 1 } { -3 1 } p/mod ptrim [ . ] bi@</syntaxhighlight>
{{out}}
<pre>
V{ -27 -9 1 }
V{ -123 }
</pre>
 
Line 1,149 ⟶ 1,595:
{{works with|Fortran|95 and later}}
 
<langsyntaxhighlight lang="fortran">module Polynom
implicit none
 
Line 1,228 ⟶ 1,674:
end subroutine poly_print
 
end module Polynom</langsyntaxhighlight>
 
<langsyntaxhighlight lang="fortran">program PolyDivTest
use Polynom
implicit none
Line 1,247 ⟶ 1,693:
deallocate(q, r)
 
end program PolyDivTest</langsyntaxhighlight>
 
=={{Header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">#define EPS 1.0e-20
 
type polyterm
degree as uinteger
coeff as double
end type
 
sub poly_print( P() as double )
dim as string outstr = "", sri
for i as integer = ubound(P) to 0 step -1
if outstr<>"" then
if P(i)>0 then outstr = outstr + " + "
if P(i)<0 then outstr = outstr + " - "
end if
if P(i)=0 then continue for
if abs(P(i))<>1 or i=0 then
if outstr="" then
outstr = outstr + str((P(i)))
else
outstr = outstr + str(abs(P(i)))
end if
end if
if i>0 then outstr=outstr+"x"
sri= str(i)
if i>1 then outstr=outstr + "^" + sri
next i
print outstr
end sub
 
function lc_deg( B() as double ) as polyterm
'gets the coefficent and degree of the leading term in a polynomial
dim as polyterm ret
for i as uinteger = ubound(B) to 0 step -1
if B(i)<>0 then
ret.degree = i
ret.coeff = B(i)
return ret
end if
next i
return ret
end function
 
sub poly_multiply( byval k as polyterm, P() as double )
'in-place multiplication of polynomial by a polynomial term
dim i as integer
for i = ubound(P) to k.degree step -1
P(i) = k.coeff*P(i-k.degree)
next i
for i = k.degree-1 to 0 step -1
P(i)=0
next i
end sub
 
sub poly_subtract( P() as double, Q() as double )
'in place subtraction of one polynomial from another
dim as uinteger deg = ubound(P)
for i as uinteger = 0 to deg
P(i) -= Q(i)
if abs(P(i))<EPS then P(i)=0 'stupid floating point subtraction, grumble grumble
next i
end sub
 
sub poly_add( P() as double, byval t as polyterm )
'in-place addition of a polynomial term to a polynomial
P(t.degree) += t.coeff
end sub
 
sub poly_copy( source() as double, target() as double )
for i as uinteger = 0 to ubound(source)
target(i) = source(i)
next i
end sub
 
sub polydiv( A() as double, B() as double, Q() as double, R() as double )
dim as polyterm s
dim as double sB(0 to ubound(B))
poly_copy A(), R()
dim as uinteger d = ubound(B), degr = lc_deg(R()).degree
dim as double c = lc_deg(B()).coeff
while degr >= d
s.coeff = lc_deg(R()).coeff/c
s.degree = degr - d
poly_add Q(), s
poly_copy B(), sB()
redim preserve sB(0 to s.degree+ubound(sB)) as double
poly_multiply s, sB()
poly_subtract R(), sB()
degr = lc_deg(R()).degree
redim sB(0 to ubound(B))
wend
end sub
 
dim as double N(0 to 4) = {-42, 0, -12, 1} 'x^3 - 12x^2 - 42
dim as double D(0 to 2) = {-3, 1} ' x - 3
dim as double Q(0 to ubound(N)), R(0 to ubound(N))
 
polydiv( N(), D(), Q(), R() )
 
poly_print Q() 'quotient
poly_print R() 'remainder</syntaxhighlight>
{{out}}
<pre>x^2 - 9x - 27
-123</pre>
 
=={{header|GAP}}==
GAP has built-in functions for computations with polynomials.
<syntaxhighlight lang="gap">x := Indeterminate(Rationals, "x");
p := x^11 + 3*x^8 + 7*x^2 + 3;
q := x^7 + 5*x^3 + 1;
QuotientRemainder(p, q);
# [ x^4+3*x-5, -16*x^4+25*x^3+7*x^2-3*x+8 ]</syntaxhighlight>
 
=={{header|Go}}==
By the convention and pseudocode given in the task:
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,296 ⟶ 1,855:
}
return q, nn, true
}</langsyntaxhighlight>
Output:
<pre>
Line 1,304 ⟶ 1,863:
R: [-123 0 0 0]
</pre>
 
=={{header|GAP}}==
GAP has built-in functions for computations with polynomials.
<lang gap>x := Indeterminate(Rationals, "x");
p := x^11 + 3*x^8 + 7*x^2 + 3;
q := x^7 + 5*x^3 + 1;
QuotientRemainder(p, q);
# [ x^4+3*x-5, -16*x^4+25*x^3+7*x^2-3*x+8 ]</lang>
 
=={{header|Haskell}}==
Line 1,317 ⟶ 1,868:
Translated from the OCaml code elsewhere on the page.
{{works with|GHC|6.10}}
<langsyntaxhighlight lang="haskell">import Data.List
 
shift n l = l ++ replicate n 0
Line 1,338 ⟶ 1,889:
ks = map (* k) $ shift ddif s
q' = zipWith' (+) q $ shift ddif [k]
f' = norm $ tail $ zipWith' (-) f ks</langsyntaxhighlight>
 
And this is the also-translated pretty printing function.
 
<langsyntaxhighlight lang="haskell">str_poly l = intercalate " + " $ terms l
where term v 0 = show v
term 1 1 = "x"
Line 1,352 ⟶ 1,903:
terms [] = []
terms (0:t) = terms t
terms (h:t) = (term h (length t)) : (terms t)</langsyntaxhighlight>
 
=={{header|J}}==
Line 1,358 ⟶ 1,909:
From http://www.jsoftware.com/jwiki/Phrases/Polynomials
 
<langsyntaxhighlight Jlang="j">divmod=:[: (}: ; {:) ([ (] -/@,:&}. (* {:)) ] , %&{.~)^:(>:@-~&#)&.|.~</langsyntaxhighlight>
 
Wikipedia example:
<langsyntaxhighlight Jlang="j">_42 0 _12 1 divmod _3 1</langsyntaxhighlight>
This produces the result:
┌────────┬────┐
Line 1,370 ⟶ 1,921:
 
=={{header|Java}}==
Replace existing translation.
{{trans|Kotlin}}
<br><br>
<lang Java>import java.util.Arrays;
When generalized, the coefficients of polynomial division are fractions. This implementation supports integer and fraction coefficients.
<br><br>
To test and validate the results, polynomial multiplication and addition are also implemented.
<syntaxhighlight lang="java">
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
public class PolynomialLongDivision {
private static class Solution {
public static void main(String[] args) {
double[] quotient, remainder;
RunDivideTest(new Polynomial(1, 3, -12, 2, -42, 0), new Polynomial(1, 1, -3, 0));
RunDivideTest(new Polynomial(5, 2, 4, 1, 1, 0), new Polynomial(2, 1, 3, 0));
RunDivideTest(new Polynomial(5, 10, 4, 7, 1, 0), new Polynomial(2, 4, 2, 2, 3, 0));
RunDivideTest(new Polynomial(2,7,-24,6,2,5,-108,4,3,3,-120,2,-126,0), new Polynomial(2, 4, 2, 2, 3, 0));
}
private static void RunDivideTest(Polynomial p1, Polynomial p2) {
Polynomial[] result = p1.divide(p2);
System.out.printf("Compute: (%s) / (%s) = %s reminder %s%n", p1, p2, result[0], result[1]);
System.out.printf("Test: (%s) * (%s) + (%s) = %s%n%n", result[0], p2, result[1], result[0].multiply(p2).add(result[1]));
}
private static final class Polynomial {
 
private List<Term> polynomialTerms;
Solution(double[] q, double[] r) {
this.quotient = q;
// Format - coeff, exp, coeff, exp, (repeating in pairs) . . .
this.remainder = r;
public Polynomial(long ... values) {
if ( values.length % 2 != 0 ) {
throw new IllegalArgumentException("ERROR 102: Polynomial constructor. Length must be even. Length = " + values.length);
}
polynomialTerms = new ArrayList<>();
for ( int i = 0 ; i < values.length ; i += 2 ) {
polynomialTerms.add(new Term(BigInteger.valueOf(values[i]), values[i+1]));
}
Collections.sort(polynomialTerms, new TermSorter());
}
public Polynomial() {
// zero
polynomialTerms = new ArrayList<>();
polynomialTerms.add(new Term(BigInteger.ZERO, 0));
}
private Polynomial(List<Term> termList) {
if ( termList.size() != 0 ) {
// Remove zero terms if needed
for ( int i = 0 ; i < termList.size() ; i++ ) {
if ( termList.get(i).coefficient.compareTo(Integer.ZERO_INT) == 0 ) {
termList.remove(i);
}
}
}
if ( termList.size() == 0 ) {
// zero
termList.add(new Term(BigInteger.ZERO,0));
}
polynomialTerms = termList;
Collections.sort(polynomialTerms, new TermSorter());
}
public Polynomial[] divide(Polynomial v) {
Polynomial q = new Polynomial();
Polynomial r = this;
Number lcv = v.leadingCoefficient();
long dv = v.degree();
while ( r.degree() >= dv ) {
Number lcr = r.leadingCoefficient();
Number s = lcr.divide(lcv);
Term term = new Term(s, r.degree() - dv);
q = q.add(term);
r = r.add(v.multiply(term.negate()));
}
return new Polynomial[] {q, r};
}
}
 
public Polynomial add(Polynomial polynomial) {
private static int polyDegree(double[] p) {
for (int i = p.lengthList<Term> -termList 1;= inew ArrayList<>= 0(); --i) {
ifint (p[i]thisCount != 0polynomialTerms.0size() return i;
int polyCount = polynomial.polynomialTerms.size();
while ( thisCount > 0 || polyCount > 0 ) {
Term thisTerm = thisCount == 0 ? null : polynomialTerms.get(thisCount-1);
Term polyTerm = polyCount == 0 ? null : polynomial.polynomialTerms.get(polyCount-1);
if ( thisTerm == null ) {
termList.add(polyTerm);
polyCount--;
}
else if (polyTerm == null ) {
termList.add(thisTerm);
thisCount--;
}
else if ( thisTerm.degree() == polyTerm.degree() ) {
Term t = thisTerm.add(polyTerm);
if ( t.coefficient.compareTo(Integer.ZERO_INT) != 0 ) {
termList.add(t);
}
thisCount--;
polyCount--;
}
else if ( thisTerm.degree() < polyTerm.degree() ) {
termList.add(thisTerm);
thisCount--;
}
else {
termList.add(polyTerm);
polyCount--;
}
}
return new Polynomial(termList);
}
return Integer.MIN_VALUE;
}
 
public Polynomial add(Term term) {
private static double[] polyShiftRight(double[] p, int places) {
if (places List<=Term> 0)termList return= pnew ArrayList<>();
int pd boolean added = polyDegree(p)false;
if for (pd +int placesindex >= p0 ; index < polynomialTerms.lengthsize() ; index++ ) {
Term currentTerm = polynomialTerms.get(index);
throw new IllegalArgumentException("The number of places to be shifted is too large");
if ( currentTerm.exponent == term.exponent ) {
added = true;
if ( currentTerm.coefficient.add(term.coefficient).compareTo(Integer.ZERO_INT) != 0 ) {
termList.add(currentTerm.add(term));
}
}
else {
termList.add(currentTerm);
}
}
if ( ! added ) {
termList.add(term);
}
return new Polynomial(termList);
}
 
double[] d = Arrays.copyOf(p, p.length);
forpublic Polynomial multiply(int i = pd; i >= 0;Polynomial --ipolynomial) {
d[iList<Term> + places]termList = d[i]new ArrayList<>();
d[for ( int i] = 0 ; i < polynomialTerms.0size() ; i++ ) {
Term ci = polynomialTerms.get(i);
for ( int j = 0 ; j < polynomial.polynomialTerms.size() ; j++ ) {
Term cj = polynomial.polynomialTerms.get(j);
Term currentTerm = ci.multiply(cj);
boolean added = false;
for ( int k = 0 ; k < termList.size() ; k++ ) {
if ( currentTerm.exponent == termList.get(k).exponent ) {
added = true;
Term t = termList.remove(k).add(currentTerm);
if ( t.coefficient.compareTo(Integer.ZERO_INT) != 0 ) {
termList.add(t);
}
break;
}
}
if ( ! added ) {
termList.add(currentTerm);
}
}
}
return new Polynomial(termList);
}
 
public Polynomial multiply(Term term) {
List<Term> termList = new ArrayList<>();
for ( int index = 0 ; index < polynomialTerms.size() ; index++ ) {
Term currentTerm = polynomialTerms.get(index);
termList.add(currentTerm.multiply(term));
}
return new Polynomial(termList);
}
 
public Number leadingCoefficient() {
return polynomialTerms.get(0).coefficient;
}
 
public long degree() {
return polynomialTerms.get(0).exponent;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
boolean first = true;
for ( Term term : polynomialTerms ) {
if ( first ) {
sb.append(term);
first = false;
}
else {
sb.append(" ");
if ( term.coefficient.compareTo(Integer.ZERO_INT) > 0 ) {
sb.append("+ ");
sb.append(term);
}
else {
sb.append("- ");
sb.append(term.negate());
}
}
}
return sb.toString();
}
return d;
}
private static final class TermSorter implements Comparator<Term> {
@Override
public int compare(Term o1, Term o2) {
return (int) (o2.exponent - o1.exponent);
}
}
private static final class Term {
Number coefficient;
long exponent;
public Term(BigInteger c, long e) {
coefficient = new Integer(c);
exponent = e;
}
 
private static void polyMultiply public Term(double[]Number pc, doublelong me) {
for (int i = 0;coefficient i= < p.lengthc; ++i) {
p[i]exponent *= me;
}
 
public Term multiply(Term term) {
return new Term(coefficient.multiply(term.coefficient), exponent + term.exponent);
}
public Term add(Term term) {
if ( exponent != term.exponent ) {
throw new RuntimeException("ERROR 102: Exponents not equal.");
}
return new Term(coefficient.add(term.coefficient), exponent);
}
 
public Term negate() {
return new Term(coefficient.negate(), exponent);
}
public long degree() {
return exponent;
}
@Override
public String toString() {
if ( coefficient.compareTo(Integer.ZERO_INT) == 0 ) {
return "0";
}
if ( exponent == 0 ) {
return "" + coefficient;
}
if ( coefficient.compareTo(Integer.ONE_INT) == 0 ) {
if ( exponent == 1 ) {
return "x";
}
else {
return "x^" + exponent;
}
}
if ( exponent == 1 ) {
return coefficient + "x";
}
return coefficient + "x^" + exponent;
}
}
 
private static voidabstract polySubtract(double[]class p, double[] s)Number {
forpublic abstract (int icompareTo(Number = 0in); i < p.length; ++i) {
public abstract Number p[i] -= s[i]negate();
public abstract Number add(Number in);
public abstract Number multiply(Number in);
public abstract Number inverse();
public abstract boolean isInteger();
public abstract boolean isFraction();
public Number subtract(Number in) {
return add(in.negate());
}
public Number divide(Number in) {
return multiply(in.inverse());
}
}
 
privatepublic static Solutionclass polyLongDiv(double[]Fraction n,extends double[] d)Number {
 
if (n.length != d.length) {
private final Integer numerator;
throw new IllegalArgumentException("Numerator and denominator vectors must have the same size");
private final Integer denominator;
 
public Fraction(Integer n, Integer d) {
numerator = n;
denominator = d;
}
int nd = polyDegree(n);
int dd = polyDegree(d);@Override
ifpublic (ddint <compareTo(Number 0in) {
if ( in.isInteger() ) {
throw new IllegalArgumentException("Divisor must have at least one one-zero coefficient");
Integer result = ((Integer) in).multiply(denominator);
return numerator.compareTo(result);
}
else if ( in.isFraction() ) {
Fraction inFrac = (Fraction) in;
Integer left = numerator.multiply(inFrac.denominator);
Integer right = denominator.multiply(inFrac.numerator);
return left.compareTo(right);
}
throw new RuntimeException("ERROR: Unknown number type in Fraction.compareTo");
}
 
if (nd < dd) {
@Override
throw new IllegalArgumentException("The degree of the divisor cannot exceed that of the numerator");
public Number negate() {
if ( denominator.integer.signum() < 0 ) {
return new Fraction(numerator, (Integer) denominator.negate());
}
return new Fraction((Integer) numerator.negate(), denominator);
}
 
double[] n2 = Arrays.copyOf(n, n.length);
@Override
double[] q = new double[n.length];
whilepublic (ndNumber >=add(Number ddin) {
double[]if d2( = polyShiftRightin.isInteger(d,) nd - dd); {
q[nd - dd] = n2[nd] //x/y+z d2[nd];= (x+yz)/y
return new Fraction((Integer) ((Integer) in).multiply(denominator).add(numerator), denominator);
polyMultiply(d2, q[nd - dd]);
polySubtract(n2, d2);}
ndelse =if polyDegree(n2 in.isFraction(); ) {
Fraction inFrac = (Fraction) in;
// compute a/b + x/y
// Let q = gcd(b,y)
// Result = ( (a*y + x*b)/q ) / ( b*y/q )
Integer x = inFrac.numerator;
Integer y = inFrac.denominator;
Integer q = y.gcd(denominator);
Integer temp1 = numerator.multiply(y);
Integer temp2 = denominator.multiply(x);
Integer newDenom = denominator.multiply(y).divide(q);
if ( newDenom.compareTo(Integer.ONE_INT) == 0 ) {
return temp1.add(temp2);
}
Integer newNum = (Integer) temp1.add(temp2).divide(q);
Integer gcd2 = newDenom.gcd(newNum);
if ( gcd2.compareTo(Integer.ONE_INT) == 0 ) {
return new Fraction(newNum, newDenom);
}
newNum = newNum.divide(gcd2);
newDenom = newDenom.divide(gcd2);
if ( newDenom.compareTo(Integer.ONE_INT) == 0 ) {
return newNum;
}
else if ( newDenom.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
return newNum.negate();
}
return new Fraction(newNum, newDenom);
}
throw new RuntimeException("ERROR: Unknown number type in Fraction.compareTo");
}
return new Solution(q, n2);
}
 
@Override
private static void polyShow(double[] p) {
intpublic pdNumber = polyDegreemultiply(pNumber in); {
for (int i = pd;if i( >= 0;in.isInteger() --i) {
double coeff //x/y*z = p[i];x*z/y
if (coeff = Integer temp = 0numerator.0multiply((Integer) continuein);
if (coeff = Integer gcd = 1temp.0gcd(denominator) {;
if (i <gcd.compareTo(Integer.ONE_INT) == 0 || gcd.compareTo(Integer.MINUS_ONE_INT) == 0 pd) {
System.out.print("return +new Fraction(temp, "denominator);
}
} else if (coeff =Integer newTop = -1temp.0divide(gcd) {;
ifInteger (inewBot <= pddenominator.divide(gcd) {;
if ( SystemnewBot.out.printcompareTo("Integer.ONE_INT) -== 0 "); {
} else { return newTop;
System.out.print("-");
}
} else if (coeff <newBot.compareTo(Integer.MINUS_ONE_INT) == 0.0 ) {
if (i < pd) {return newTop.negate();
System.out.printf(" - %.1f", -coeff);
} else {
System.out.print(coeff);
}
} else { return new Fraction(newTop, newBot);
if (i < pd) {}
else if ( Systemin.out.printfisFraction(") +) %.1f", coeff);{
}Fraction elseinFrac {= (Fraction) in;
// compute a/b System.out.print(coeff);* x/y
Integer tempTop = numerator.multiply(inFrac.numerator);
Integer tempBot = denominator.multiply(inFrac.denominator);
Integer gcd = tempTop.gcd(tempBot);
if ( gcd.compareTo(Integer.ONE_INT) == 0 || gcd.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
return new Fraction(tempTop, tempBot);
}
Integer newTop = tempTop.divide(gcd);
Integer newBot = tempBot.divide(gcd);
if ( newBot.compareTo(Integer.ONE_INT) == 0 ) {
return newTop;
}
if ( newBot.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
return newTop.negate();
}
return new Fraction(newTop, newBot);
}
ifthrow new RuntimeException(i"ERROR: > 1)Unknown Systemnumber type in Fraction.out.printf(compareTo"x^%d", i);
}
else if (i == 1) System.out.print("x");
 
@Override
public boolean isInteger() {
return false;
}
 
@Override
public boolean isFraction() {
return true;
}
@Override
public String toString() {
return numerator.toString() + "/" + denominator.toString();
}
 
@Override
public Number inverse() {
if ( numerator.equals(Integer.ONE_INT) ) {
return denominator;
}
else if ( numerator.equals(Integer.MINUS_ONE_INT) ) {
return denominator.negate();
}
else if ( numerator.integer.signum() < 0 ) {
return new Fraction((Integer) denominator.negate(), (Integer) numerator.negate());
}
return new Fraction(denominator, numerator);
}
System.out.println();
}
public static class Integer extends Number {
 
private BigInteger integer;
public static final Integer MINUS_ONE_INT = new Integer(new BigInteger("-1"));
public static final Integer ONE_INT = new Integer(new BigInteger("1"));
public static final Integer ZERO_INT = new Integer(new BigInteger("0"));
public Integer(BigInteger number) {
this.integer = number;
}
public int compareTo(Integer val) {
return integer.compareTo(val.integer);
}
 
@Override
public int compareTo(Number in) {
if ( in.isInteger() ) {
return compareTo((Integer) in);
}
else if ( in.isFraction() ) {
Fraction frac = (Fraction) in;
BigInteger result = integer.multiply(frac.denominator.integer);
return result.compareTo(frac.numerator.integer);
}
throw new RuntimeException("ERROR: Unknown number type in Integer.compareTo");
}
 
@Override
public Number negate() {
return new Integer(integer.negate());
}
 
public Integer add(Integer in) {
return new Integer(integer.add(in.integer));
}
@Override
public Number add(Number in) {
if ( in.isInteger() ) {
return add((Integer) in);
}
else if ( in.isFraction() ) {
Fraction f = (Fraction) in;
Integer top = f.numerator;
Integer bot = f.denominator;
return new Fraction((Integer) multiply(bot).add(top), bot);
}
throw new RuntimeException("ERROR: Unknown number type in Integer.add");
}
 
@Override
public Number multiply(Number in) {
if ( in.isInteger() ) {
return multiply((Integer) in);
}
else if ( in.isFraction() ) {
// a * x/y = ax/y
Integer x = ((Fraction) in).numerator;
Integer y = ((Fraction) in).denominator;
Integer temp = (Integer) multiply(x);
Integer gcd = temp.gcd(y);
if ( gcd.compareTo(Integer.ONE_INT) == 0 || gcd.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
return new Fraction(temp, y);
}
Integer newTop = temp.divide(gcd);
Integer newBot = y.divide(gcd);
if ( newBot.compareTo(Integer.ONE_INT) == 0 ) {
return newTop;
}
if ( newBot.compareTo(Integer.MINUS_ONE_INT) == 0 ) {
return newTop.negate();
}
return new Fraction(newTop, newBot);
}
throw new RuntimeException("ERROR: Unknown number type in Integer.add");
}
 
public Integer gcd(Integer in) {
return new Integer(integer.gcd(in.integer));
}
 
public Integer divide(Integer in) {
return new Integer(integer.divide(in.integer));
}
 
public Integer multiply(Integer in) {
return new Integer(integer.multiply(in.integer));
}
 
@Override
public boolean isInteger() {
return true;
}
 
@Override
public boolean isFraction() {
return false;
}
 
@Override
public String toString() {
return integer.toString();
}
 
@Override
public Number inverse() {
if ( equals(ZERO_INT) ) {
throw new RuntimeException("Attempting to take the inverse of zero in IntegerExpression");
}
else if ( this.compareTo(ONE_INT) == 0 ) {
return ONE_INT;
}
else if ( this.compareTo(MINUS_ONE_INT) == 0 ) {
return MINUS_ONE_INT;
}
return new Fraction(ONE_INT, this);
}
 
public static void main(String[] args) {
double[] n = new double[]{-42.0, 0.0, -12.0, 1.0};
double[] d = new double[]{-3.0, 1.0, 0.0, 0.0};
System.out.print("Numerator : ");
polyShow(n);
System.out.print("Denominator : ");
polyShow(d);
System.out.println("-------------------------------------");
Solution sol = polyLongDiv(n, d);
System.out.print("Quotient : ");
polyShow(sol.quotient);
System.out.print("Remainder : ");
polyShow(sol.remainder);
}
}
}</lang>
</syntaxhighlight>
{{out}}
<pre>
<pre>Numerator : x^3 - 12.0x^2 - 42.0
Compute: (x^3 - 12x^2 - 42) / (x - 3) = x^2 - 9x - 27 reminder -123
Denominator : x - 3.0
Test: (x^2 - 9x - 27) * (x - 3) + (-123) = x^3 - 12x^2 - 42
-------------------------------------
 
Quotient : x^2 - 9.0x - 27.0
Compute: (5x^2 + 4x + 1) / (2x + 3) = 5/2x - 7/4 reminder 25/4
Remainder : -123.0</pre>
Test: (5/2x - 7/4) * (2x + 3) + (25/4) = 5x^2 + 4x + 1
 
Compute: (5x^10 + 4x^7 + 1) / (2x^4 + 2x^2 + 3) = 5/2x^6 - 5/2x^4 + 2x^3 - 5/4x^2 - 2x + 5 reminder -2x^3 - 25/4x^2 + 6x - 14
Test: (5/2x^6 - 5/2x^4 + 2x^3 - 5/4x^2 - 2x + 5) * (2x^4 + 2x^2 + 3) + (-2x^3 - 25/4x^2 + 6x - 14) = 5x^10 + 4x^7 + 1
 
Compute: (2x^7 - 24x^6 + 2x^5 - 108x^4 + 3x^3 - 120x^2 - 126) / (2x^4 + 2x^2 + 3) = x^3 - 12x^2 - 42 reminder 0
Test: (x^3 - 12x^2 - 42) * (2x^4 + 2x^2 + 3) + (0) = 2x^7 - 24x^6 + 2x^5 - 108x^4 + 3x^3 - 120x^2 - 126
</pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq, and with fq'''
 
'''Adapted from the second version in the [[#Wren|Wren]] entry.'''
 
In this entry, polynomials are represented by JSON arrays exactly as
in the task description; that is, using jq notation, `.[$i]` corresponds to
the coefficient of {\displaystyle x^i}.
<syntaxhighlight lang=jq>
# Emit the canonical form of the polynomical represented by the input array
def canonical:
if length == 0 then .
elif .[-1] == 0 then .[:-1]|canonical
else .
end;
 
# string representation
def poly2s: "Polynomial(\(join(",")))";
 
# Polynomial division
# Output [ quotient, remainder]
def divrem($divisor):
($divisor|canonical) as $divisor
| { curr: canonical}
| .base = ((.curr|length) - ($divisor|length))
| until( .base < 0;
(.curr[-1] / $divisor[-1]) as $res
| .result += [$res]
| .curr |= .[0:-1]
| reduce range (0;$divisor|length-1) as $i (.;
.curr[.base + $i] += (- $res * $divisor[$i]) )
| .base += -1
)
| [(.result | reverse), (.curr | canonical)];
 
def demo($num; $den):
{$num, $den,
res: ($num | divrem($den)) }
| .quot = .res[0]
| .rem = .res[1]
| del(.res)
| map_values(poly2s)
| "\(.num) / \(.den) = \(.quot) remainder \(.rem)";
 
demo( [-42, 0, -12, 1]; [-3, 1, 0, 0])
</syntaxhighlight>
{{output}}
<pre>
Polynomial(-42,0,-12,1) / Polynomial(-3,1,0,0) = Polynomial(-27,-9,1)
remainder Polynomial(-123)
</pre>
 
=={{header|Julia}}==
This task is straightforward with the help of Julia's [https://github.com/Keno/Polynomials.jl Polynomials] package.
<syntaxhighlight lang="julia">
<lang Julia>
using Polynomials
 
Line 1,507 ⟶ 2,550:
 
println(p, " divided by ", q, " is ", d, " with remainder ", r, ".")
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,515 ⟶ 2,558:
 
=={{header|Kotlin}}==
===Version 1===
<lang scala>// version 1.1.51
<syntaxhighlight lang="scala">// version 1.1.51
 
typealias IAE = IllegalArgumentException
 
data class Solution(val quotient: DoubleArray, val remainder: DoubleArray)
 
fun polyDegree(p: DoubleArray): Int {
for (i in p.size - 1 downTo 0) {
Line 1,527 ⟶ 2,571:
return Int.MIN_VALUE
}
 
fun polyShiftRight(p: DoubleArray, places: Int): DoubleArray {
if (places <= 0) return p
Line 1,541 ⟶ 2,585:
return d
}
 
fun polyMultiply(p: DoubleArray, m: Double) {
for (i in 0 until p.size) p[i] *= m
}
 
fun polySubtract(p: DoubleArray, s: DoubleArray) {
for (i in 0 until p.size) p[i] -= s[i]
}
 
fun polyLongDiv(n: DoubleArray, d: DoubleArray): Solution {
if (n.size != d.size) {
Line 1,573 ⟶ 2,617:
return Solution(q, n2)
}
 
fun polyShow(p: DoubleArray) {
val pd = polyDegree(p)
Line 1,590 ⟶ 2,634:
println()
}
 
fun main(args: Array<String>) {
val n = doubleArrayOf(-42.0, 0.0, -12.0, 1.0)
Line 1,604 ⟶ 2,648:
print("Remainder : ")
polyShow(r)
}</langsyntaxhighlight>
 
{{out}}
<pre>
Output:
 
Numerator : x^3 - 12.0x^2 - 42.0
Denominator : x - 3.0
Line 1,613 ⟶ 2,659:
Quotient : x^2 - 9.0x - 27.0
Remainder : -123.0
</pre>
<br>
===Version 2===
More succinct version that provides an easy-to-use API.
<syntaxhighlight lang="scala">class Polynom(private vararg val factors: Double) {
 
operator fun div(divisor: Polynom): Pair<Polynom, Polynom> {
var curr = canonical().factors
val right = divisor.canonical().factors
 
val result = mutableListOf<Double>()
for (base in curr.size - right.size downTo 0) {
val res = curr.last() / right.last()
result += res
curr = curr.copyOfRange(0, curr.size - 1)
for (i in 0 until right.size - 1)
curr[base + i] -= res * right[i]
}
 
val quot = Polynom(*result.asReversed().toDoubleArray())
val rem = Polynom(*curr).canonical()
return Pair(quot, rem)
}
 
private fun canonical(): Polynom {
if (factors.last() != 0.0) return this
for (newLen in factors.size downTo 1)
if (factors[newLen - 1] != 0.0)
return Polynom(*factors.copyOfRange(0, newLen))
return Polynom(factors[0])
}
 
override fun toString() = "Polynom(${factors.joinToString(" ")})"
}
 
fun main() {
val num = Polynom(-42.0, 0.0, -12.0, 1.0)
val den = Polynom(-3.0, 1.0, 0.0, 0.0)
 
val (quot, rem) = num / den
 
print("$num / $den = $quot remainder $rem")
}</syntaxhighlight>
 
{{out}}
<pre>
Polynom(-42.0 0.0 -12.0 1.0) / Polynom(-3.0 1.0 0.0 0.0) = Polynom(-27.0 -9.0 1.0) remainder Polynom(-123.0)
</pre>
 
=={{header|Maple}}==
As Maple is a symbolic computation system, polynomial arithmetic is, of course, provided by the language runtime. The remainder (rem) and quotient (quo) operations each allow for the other to be computed simultaneously by passing an unassigned name as an optional fourth argument. Since rem and quo deal also with multivariate polynomials, the indeterminate is passed as the third argument.
<syntaxhighlight lang="maple">
<lang Maple>
> p := randpoly( x ); # pick a random polynomial in x
5 4 3 2
Line 1,637 ⟶ 2,730:
> expand( (x^2+2)*q + r - p ); # check
0
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">PolynomialQuotientRemainder[x^3-12 x^2-42,x-3,x]</langsyntaxhighlight>
output:
<pre>{-27 - 9 x + x^2, -123}</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">const MinusInfinity = -1
 
type
Polynomial = seq[int]
Term = tuple[coeff, exp: int]
 
func degree(p: Polynomial): int =
## Return the degree of a polynomial.
## "p" is supposed to be normalized.
result = if p.len > 0: p.len - 1 else: MinusInfinity
 
func normalize(p: var Polynomial) =
## Normalize a polynomial, removing useless zeroes.
while p[^1] == 0: discard p.pop()
 
func `shr`(p: Polynomial; n: int): Polynomial =
## Shift a polynomial of "n" positions to the right.
result.setLen(p.len + n)
result[n..^1] = p
 
func `*=`(p: var Polynomial; n: int) =
## Multiply in place a polynomial by an integer.
for item in p.mitems: item *= n
p.normalize()
 
func `-=`(a: var Polynomial; b: Polynomial) =
## Substract in place a polynomial from another polynomial.
for i, val in b: a[i] -= val
a.normalize()
 
func longdiv(a, b: Polynomial): tuple[q, r: Polynomial] =
## Compute the long division of a polynomial by another.
## Return the quotient and the remainder as polynomials.
result.r = a
if b.degree < 0: raise newException(DivByZeroDefect, "divisor cannot be zero.")
result.q.setLen(a.len)
while (let k = result.r.degree - b.degree; k >= 0):
var d = b shr k
result.q[k] = result.r[^1] div d[^1]
d *= result.q[k]
result.r -= d
result.q.normalize()
 
const Superscripts: array['0'..'9', string] = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"]
 
func superscript(n: Natural): string =
## Return the Unicode string to use to represent an exponent.
if n == 1:
return ""
for d in $n:
result.add(Superscripts[d])
 
func `$`(term: Term): string =
## Return the string representation of a term.
if term.coeff == 0: "0"
elif term.exp == 0: $term.coeff
else:
let base = 'x' & superscript(term.exp)
if term.coeff == 1: base
elif term.coeff == -1: '-' & base
else: $term.coeff & base
 
func `$`(poly: Polynomial): string =
## return the string representation of a polynomial.
for idx in countdown(poly.high, 0):
let coeff = poly[idx]
var term: Term = (coeff: coeff, exp: idx)
if result.len == 0:
result.add $term
else:
if coeff > 0:
result.add '+'
result.add $term
elif coeff < 0:
term.coeff = -term.coeff
result.add '-'
result.add $term
 
 
const
N = @[-42, 0, -12, 1]
D = @[-3, 1]
 
let (q, r) = longdiv(N, D)
echo "N = ", N
echo "D = ", D
echo "q = ", q
echo "r = ", r</syntaxhighlight>
 
{{out}}
<pre>N = x³-12x²-42
D = x-3
q = x²-9x-27
r = -123</pre>
 
=={{header|OCaml}}==
 
First define some utility operations on polynomials as lists (with highest power coefficient first).
<langsyntaxhighlight lang="ocaml">let rec shift n l = if n <= 0 then l else shift (pred n) (l @ [0.0])
let rec pad n l = if n <= 0 then l else pad (pred n) (0.0 :: l)
let rec norm = function | 0.0 :: tl -> norm tl | x -> x
Line 1,654 ⟶ 2,843:
let zip op p q =
let d = (List.length p) - (List.length q) in
List.map2 op (pad (-d) p) (pad d q)</langsyntaxhighlight>
Then the main polynomial division function
<langsyntaxhighlight lang="ocaml">let polydiv f g =
let rec aux f s q =
let ddif = (deg f) - (deg s) in
Line 1,665 ⟶ 2,854:
and f' = norm (List.tl (zip (-.) f ks)) in
aux f' s q' in
aux (norm f) (norm g) []</langsyntaxhighlight>
For output we need a pretty-printing function
<langsyntaxhighlight lang="ocaml">let str_poly l =
let term v p = match (v, p) with
| ( _, 0) -> string_of_float v
Line 1,678 ⟶ 2,867:
| h :: t ->
if h = 0.0 then (terms t) else (term h (List.length t)) :: (terms t) in
String.concat " + " (terms l)</langsyntaxhighlight>
and then the example
<langsyntaxhighlight lang="ocaml">let _ =
let f = [1.0; -4.0; 6.0; 5.0; 3.0] and g = [1.0; 2.0; 1.0] in
let q, r = polydiv f g in
Printf.printf
" (%s) div (%s)\ngives\nquotient:\t(%s)\nremainder:\t(%s)\n"
(str_poly f) (str_poly g) (str_poly q) (str_poly r)</langsyntaxhighlight>
gives the output:
<pre>
Line 1,697 ⟶ 2,886:
Octave has already facilities to divide two polynomials (<code>deconv(n,d)</code>); and the reason to adopt the convention of keeping the highest power coefficient first, is to make the code compatible with builtin functions: we can use <tt>polyout</tt> to output the result.
 
<langsyntaxhighlight lang="octave">function [q, r] = poly_long_div(n, d)
gd = length(d);
pv = zeros(1, length(n));
Line 1,733 ⟶ 2,922:
[q, r] = poly_long_div([1,3], [1,-12,0,-42]);
polyout(q, 'x');
polyout(r, 'x');</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
This uses the built-in PARI polynomials.
<langsyntaxhighlight lang="parigp">poldiv(a,b)={
my(rem=a%b);
[(a - rem)/b, rem]
};
poldiv(x^9+1, x^3+x-3)</langsyntaxhighlight>
Alternately, use the built-in function <code>divrem</code>:
<langsyntaxhighlight lang="parigp">divrem(x^9+1, x^3+x-3)~</langsyntaxhighlight>
 
=={{header|Perl}}==
Line 1,749 ⟶ 2,938:
 
{{trans|Octave}}
<langsyntaxhighlight lang="perl">use strict;
use List::Util qw(min);
 
Line 1,770 ⟶ 2,959:
return ( [0], $rn );
}
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="perl">sub poly_print
{
my @c = @_;
Line 1,781 ⟶ 2,970:
}
print "\n";
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="perl">my ($q, $r);
 
($q, $r) = poly_long_div([1, -12, 0, -42], [1, -3]);
Line 1,800 ⟶ 2,989:
($q, $r) = poly_long_div([1,-4,6,5,3], [1,2,1]);
poly_print(@$q);
poly_print(@$r);</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
<!--(phixonline)-->
{{Works with|rakudo|2015-12-19}}
<syntaxhighlight lang="phix">
{{trans|Perl}} for the core algorithm; original code for LaTeX pretty-printing.
-- demo\rosetta\Polynomial_long_division.exw
<lang perl6>sub poly_long_div ( @n is copy, @d ) {
with javascript_semantics
return [0], |@n if +@n < +@d;
 
function degree(sequence p)
my @q = gather while +@n >= +@d {
@n = @n Z- flat ( ( @d X* take ( @n[0] / @d[0] ) ), 0 xx * );
@n.shift;
}
 
return $(@q), $(@n);
}
 
sub xP ( $power ) { $power>1 ?? "x^$power" !! $power==1 ?? 'x' !! '' }
sub poly_print ( @c ) { join ' + ', @c.kv.map: { $^v ~ xP( @c.end - $^k ) } }
 
my @polys = [ [ 1, -12, 0, -42 ], [ 1, -3 ] ],
[ [ 1, -12, 0, -42 ], [ 1, 1, -3 ] ],
[ [ 1, 3, 2 ], [ 1, 1 ] ],
[ [ 1, -4, 6, 5, 3 ], [ 1, 2, 1 ] ];
 
say '<math>\begin{array}{rr}';
for @polys -> [ @a, @b ] {
printf Q"%s , & %s \\\\\n", poly_long_div( @a, @b ).map: { poly_print($_) };
}
say '\end{array}</math>';</lang>
 
Output:
 
<math>\begin{array}{rr}
1x^2 + -9x + -27 , & -123 \\
1x + -13 , & 16x + -81 \\
1x + 2 , & 0 \\
1x^2 + -6x + 17 , & -23x + -14 \\
\end{array}</math>
 
=={{header|Phix}}==
<lang Phix>function degree(sequence p)
for i=length(p) to 1 by -1 do
if p[i]!=0 then return i end if
Line 1,846 ⟶ 3,003:
return -1
end function
 
function poly_div(sequence n, d)
d = deep_copy(d)
while length(d)<length(n) do d &=0 end while
integer dn = degree(n),
dd = degree(d)
if dd<0 then throw("divide by zero") end if
sequence quotquo = repeat(0,dn),
rem = deep_copy(n)
while dn>=dd do
integer k = dn-dd, qk = rem[dn]/d[dd]
integer qk = n[dn]/d[dd]
quot[k+1] = qk
sequence d2 = d[1..length(d)-k]
quo[k+1] = qk
for i=1 to length(d2) do
n[-i]integer mi -= d2[-i]*qk
rem[mi] -= d2[mi]*qk
end for
dn = degree(nrem)
end while
return {quotquo,nrem} -- (n is now the remainder)
end function
 
function poly(sequence si)
-- display helper
string r = ""
for t=length(si) to 1 by -1 do
Line 1,889 ⟶ 3,048:
return r
end function
 
function polyn(sequence s)
for i=1 to length(s) do
s[i] = poly(s[i])
end for
return s
end function
 
constant tests = {{{-42,0,-12,1},{-3,1}},
{{-3,1},{-42,0,-12,1}},
Line 1,905 ⟶ 3,057:
{{-56,87,-94,-55,22,-7},{2,0,1}},
}
 
constant fmt = "%40s / %-16s = %25s rem %s\n"
 
for i=1 to length(tests) do
sequence {num,denomden} = tests[i],
{quotquo,rmdrrem} = poly_div(num,denomden)
printf(1,fmt,polynapply({num,denomden,quotquo,rmdrrem},poly))
end for</lang>
</syntaxhighlight>
{{out}}
<pre style="font-size: 12px">
<pre>
x^3 - 12x^2 - 42 / x - 3 = x^2 - 9x - 27 rem -123
x - 3 / x^3 - 12x^2 - 42 = 0 rem x - 3
Line 1,925 ⟶ 3,078:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de degree (P)
(let I NIL
(for (N . C) P
Line 1,942 ⟶ 3,095:
(set (nth Q (inc Diff)) F)
(setq N (mapcar '((N E) (- N (* E F))) N E)) ) ) )
(list Q N) ) ) )</langsyntaxhighlight>
Output:
<pre>: (divPoly (-42 0 -12 1) (-3 1 0 0))
Line 1,949 ⟶ 3,102:
=={{header|Python}}==
{{works with|Python 2.x}}
<langsyntaxhighlight lang="python"># -*- coding: utf-8 -*-
 
from itertools import izip
from math import fabs
 
def degree(poly):
Line 1,969 ⟶ 3,121:
mult = q[dN - dD] = N[-1] / float(d[-1])
d = [coeff*mult for coeff in d]
N = [fabs ( coeffN - coeffd ) for coeffN, coeffd in izip(N, d)]
dN = degree(N)
r = N
Line 1,982 ⟶ 3,134:
D = [-3, 1, 0, 0]
print " %s / %s =" % (N,D),
print " %s remainder %s" % poly_div(N, D)</langsyntaxhighlight>
 
Sample output:
Line 1,990 ⟶ 3,142:
=={{header|R}}==
{{trans|Octave}}
<langsyntaxhighlight Rlang="r">polylongdiv <- function(n,d) {
gd <- length(d)
pv <- vector("numeric", length(n))
Line 2,023 ⟶ 3,175:
r <- polylongdiv(c(1,-12,0,-42), c(1,-3))
print.polynomial(r$q)
print.polynomial(r$r)</langsyntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(define (deg p)
Line 2,062 ⟶ 3,214:
'#(-27 -9 1)
'#(-123 0)
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2018.10}}
{{trans|Perl}} for the core algorithm; original code for LaTeX pretty-printing.
<syntaxhighlight lang="raku" line>sub poly_long_div ( @n is copy, @d ) {
return [0], |@n if +@n < +@d;
 
my @q = gather while +@n >= +@d {
@n = @n Z- flat ( ( @d X* take ( @n[0] / @d[0] ) ), 0 xx * );
@n.shift;
}
 
return @q, @n;
}
 
sub xP ( $power ) { $power>1 ?? "x^$power" !! $power==1 ?? 'x' !! '' }
sub poly_print ( @c ) { join ' + ', @c.kv.map: { $^v ~ xP( @c.end - $^k ) } }
 
my @polys = [ [ 1, -12, 0, -42 ], [ 1, -3 ] ],
[ [ 1, -12, 0, -42 ], [ 1, 1, -3 ] ],
[ [ 1, 3, 2 ], [ 1, 1 ] ],
[ [ 1, -4, 6, 5, 3 ], [ 1, 2, 1 ] ];
 
say '<math>\begin{array}{rr}';
for @polys -> [ @a, @b ] {
printf Q"%s , & %s \\\\\n", poly_long_div( @a, @b ).map: { poly_print($_) };
}
say '\end{array}</math>';</syntaxhighlight>
 
Output:
 
<math>\begin{array}{rr}
1x^2 + -9x + -27 , & -123 \\
1x + -13 , & 16x + -81 \\
1x + 2 , & 0 \\
1x^2 + -6x + 17 , & -23x + -14 \\
\end{array}</math>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/* REXX needed by some... */
z='1 -12 0 -42' /* Numerator */
n='1 -3' /* Denominator */
Line 2,108 ⟶ 3,298:
d=d-1
End
Return strip(space(res,0),'L','+')</langsyntaxhighlight>
{{out}}
<pre>(x**3-12*x**2-42)/(x-3)=(x**2-9*x-27)
Remainder: -123 </pre>
 
=={{header|RPL}}==
{{works with|HP|49}}
'-42-12*X^2+X^3' 'X-3' DIV2
{{out}}
<pre>
2: 'X^2-9*X-27'
1: -123
</pre>
 
=={{header|Ruby}}==
Implementing the algorithm given in the task description:
<langsyntaxhighlight lang="ruby">def polynomial_long_division(numerator, denominator)
dd = degree(denominator)
raise ArgumentError, "denominator is zero" if dd < 0
Line 2,160 ⟶ 3,359:
q, r = polynomial_long_division(f, g)
puts "#{f} / #{g} => #{q} remainder #{r}"
# => [-42, 0, -12, 1] / [-3, 1, 1, 0] => [-13, 1, 0, 0] remainder [-81, 16, 0, 0]</langsyntaxhighlight>
 
Implementing the algorithms on the [[wp:Polynomial long division|wikipedia page]] -- uglier code but nicer user interface
<langsyntaxhighlight lang="ruby">def polynomial_division(f, g)
if g.length == 0 or (g.length == 1 and g[0] == 0)
raise ArgumentError, "denominator is zero"
Line 2,230 ⟶ 3,429:
q, r = polynomial_division(f, g)
puts "#{f} / #{g} => #{q} remainder #{r}"
# => [1, -12, 0, -42] / [1, 1, -3] => [1, -13] remainder [16, -81]</langsyntaxhighlight>
 
Best of both worlds: {{trans|Tcl}}
<langsyntaxhighlight lang="ruby">def polynomial_division(f, g)
if g.length == 0 or (g.length == 1 and g[0] == 0)
raise ArgumentError, "denominator is zero"
Line 2,261 ⟶ 3,460:
q, r = polynomial_division(f, g)
puts "#{f} / #{g} => #{q} remainder #{r}"
# => [1, -12, 0, -42] / [1, 1, -3] => [1.0, -13.0] remainder [16.0, -81.0]</langsyntaxhighlight>
 
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">func poly_long_div(rn, rd) {
 
var n = rn.map{_}
Line 2,284 ⟶ 3,483:
 
return([0], rn)
}</langsyntaxhighlight>
 
Example:
 
<langsyntaxhighlight lang="ruby">func poly_print(c) {
var l = c.len
c.each_kv {|i, n|
Line 2,309 ⟶ 3,508:
poly_print(r)
print "\n"
}</langsyntaxhighlight>
 
{{out}}
Line 2,328 ⟶ 3,527:
=={{header|Slate}}==
 
<langsyntaxhighlight Slatelang="slate">define: #Polynomial &parents: {Comparable} &slots: {#coefficients -> ExtensibleArray new}.
 
p@(Polynomial traits) new &capacity: n
Line 2,389 ⟶ 3,588:
{q. n}]
ifFalse: [{p newFrom: #(0). p copy}]
].</langsyntaxhighlight>
 
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
 
<langsyntaxhighlight lang="smalltalk">Object subclass: Polynomial [
|coeffs|
Polynomial class >> new [ ^ super basicNew init ]
Line 2,461 ⟶ 3,660:
]
displayNl [ self display. Character nl display ]
].</langsyntaxhighlight>
 
<langsyntaxhighlight lang="smalltalk">|res|
res := OrderedCollection new.
 
Line 2,473 ⟶ 3,672:
res do: [ :o |
(o at: 1) display. ' with rest: ' display. (o at: 2) displayNl
]</langsyntaxhighlight>
 
=={{header|SPAD}}==
Line 2,479 ⟶ 3,678:
{{works with|OpenAxiom}}
{{works with|Axiom}}
<langsyntaxhighlight SPADlang="spad">(1) -> monicDivide(x^3-12*x^2-42,x-3,'x)
 
2
(1) [quotient = x - 9x - 27,remainder = - 123]
 
Type: Record(quotient: Polynomial(Integer),remainder: Polynomial(Integer))</langsyntaxhighlight>
 
Domain:[http://fricas.github.io/api/PolynomialCategory.html#l-polynomial-category-monic-divide]
 
=={{header|Swift}}==
 
{{trans|Kotlin}}
 
<syntaxhighlight lang="swift">protocol Dividable {
static func / (lhs: Self, rhs: Self) -> Self
}
 
extension Int: Dividable { }
 
struct Solution<T> {
var quotient: [T]
var remainder: [T]
}
 
func polyDegree<T: SignedNumeric>(_ p: [T]) -> Int {
for i in stride(from: p.count - 1, through: 0, by: -1) where p[i] != 0 {
return i
}
 
return Int.min
}
 
func polyShiftRight<T: SignedNumeric>(p: [T], places: Int) -> [T] {
guard places > 0 else {
return p
}
 
let deg = polyDegree(p)
 
assert(deg + places < p.count, "Number of places to shift too large")
 
var res = p
 
for i in stride(from: deg, through: 0, by: -1) {
res[i + places] = res[i]
res[i] = 0
}
 
return res
}
 
func polyMul<T: SignedNumeric>(_ p: inout [T], by: T) {
for i in 0..<p.count {
p[i] *= by
}
}
 
func polySub<T: SignedNumeric>(_ p: inout [T], by: [T]) {
for i in 0..<p.count {
p[i] -= by[i]
}
}
 
func polyLongDiv<T: SignedNumeric & Dividable>(numerator n: [T], denominator d: [T]) -> Solution<T>? {
guard n.count == d.count else {
return nil
}
 
var nDeg = polyDegree(n)
let dDeg = polyDegree(d)
 
guard dDeg >= 0, nDeg >= dDeg else {
return nil
}
 
var n2 = n
var quo = [T](repeating: 0, count: n.count)
 
while nDeg >= dDeg {
let i = nDeg - dDeg
var d2 = polyShiftRight(p: d, places: i)
 
quo[i] = n2[nDeg] / d2[nDeg]
 
polyMul(&d2, by: quo[i])
polySub(&n2, by: d2)
 
nDeg = polyDegree(n2)
}
 
return Solution(quotient: quo, remainder: n2)
}
 
func polyPrint<T: SignedNumeric & Comparable>(_ p: [T]) {
let deg = polyDegree(p)
 
for i in stride(from: deg, through: 0, by: -1) where p[i] != 0 {
let coeff = p[i]
 
switch coeff {
case 1 where i < deg:
print(" + ", terminator: "")
case 1:
print("", terminator: "")
case -1 where i < deg:
print(" - ", terminator: "")
case -1:
print("-", terminator: "")
case _ where coeff < 0 && i < deg:
print(" - \(-coeff)", terminator: "")
case _ where i < deg:
print(" + \(coeff)", terminator: "")
case _:
print("\(coeff)", terminator: "")
}
 
if i > 1 {
print("x^\(i)", terminator: "")
} else if i == 1 {
print("x", terminator: "")
}
}
 
print()
}
 
let n = [-42, 0, -12, 1]
let d = [-3, 1, 0, 0]
 
print("Numerator: ", terminator: "")
polyPrint(n)
print("Denominator: ", terminator: "")
polyPrint(d)
 
guard let sol = polyLongDiv(numerator: n, denominator: d) else {
fatalError()
}
 
print("----------")
print("Quotient: ", terminator: "")
polyPrint(sol.quotient)
print("Remainder: ", terminator: "")
polyPrint(sol.remainder)</syntaxhighlight>
 
{{out}}
 
<pre>Numerator: x^3 - 12x^2 - 42
Denominator: x - 3
----------
Quotient: x^2 - 9x - 27
Remainder: -123</pre>
 
=={{header|Tcl}}==
{{works with|Tcl|8.5 and later}}
 
<langsyntaxhighlight lang="tcl"># poldiv - Divide two polynomials n and d.
# Result is a list of two polynomials, q and r, where n = qd + r
# and the degree of r is less than the degree of b.
Line 2,531 ⟶ 3,872:
lassign [poldiv {-42. 0. -12. 1.} {-3. 1. 0. 0.}] Q R
puts [list Q = $Q]
puts [list R = $R]</langsyntaxhighlight>
 
=={{header|Ursala}}==
Line 2,539 ⟶ 3,880:
of the algorithm in terms of list operations (fold, zip, map, distribute, etc.) instead
of array indexing, hence not unnecessarily verbose.
<langsyntaxhighlight lang="ursala">#import std
#import flo
 
Line 2,547 ⟶ 3,888:
@lrrPX ==!| zipp0.; @x not zeroid+ ==@h->hr ~&t,
(^lryPX/~&lrrl2C minus^*p/~&rrr times*lrlPD)^/div@bzPrrPlXO ~&,
@r ^|\~& ~&i&& :/0.)</langsyntaxhighlight>
test program:
<langsyntaxhighlight Ursalalang="ursala">#cast %eLW
 
example = polydiv(<-42.,0.,-12.,1.>,<-3.,1.,0.,0.>)</langsyntaxhighlight>
output:
<pre>(
<-2.700000e+01,-9.000000e+00,1.000000e+00>,
<-1.230000e+02>)</pre>
 
=={{header|VBA}}==
{{trans|Phix}}<syntaxhighlight lang="vb">Option Base 1
Function degree(p As Variant)
For i = UBound(p) To 1 Step -1
If p(i) <> 0 Then
degree = i
Exit Function
End If
Next i
degree = -1
End Function
Function poly_div(ByVal n As Variant, ByVal d As Variant) As Variant
If UBound(d) < UBound(n) Then
ReDim Preserve d(UBound(n))
End If
Dim dn As Integer: dn = degree(n)
Dim dd As Integer: dd = degree(d)
If dd < 0 Then
poly_div = CVErr(xlErrDiv0)
Exit Function
End If
Dim quot() As Integer
ReDim quot(dn)
Do While dn >= dd
Dim k As Integer: k = dn - dd
Dim qk As Integer: qk = n(dn) / d(dd)
quot(k + 1) = qk
Dim d2() As Variant
d2 = d
ReDim Preserve d2(UBound(d) - k)
For i = 1 To UBound(d2)
n(UBound(n) + 1 - i) = n(UBound(n) + 1 - i) - d2(UBound(d2) + 1 - i) * qk
Next i
dn = degree(n)
Loop
poly_div = Array(quot, n) '-- (n is now the remainder)
End Function
Function poly(si As Variant) As String
'-- display helper
Dim r As String
For t = UBound(si) To 1 Step -1
Dim sit As Integer: sit = si(t)
If sit <> 0 Then
If sit = 1 And t > 1 Then
r = r & IIf(r = "", "", " + ")
Else
If sit = -1 And t > 1 Then
r = r & IIf(r = "", "-", " - ")
Else
If r <> "" Then
r = r & IIf(sit < 0, " - ", " + ")
sit = Abs(sit)
End If
r = r & CStr(sit)
End If
End If
r = r & IIf(t > 1, "x" & IIf(t > 2, t - 1, ""), "")
End If
Next t
If r = "" Then r = "0"
poly = r
End Function
Function polyn(s As Variant) As String
Dim t() As String
ReDim t(2 * UBound(s))
For i = 1 To 2 * UBound(s) Step 2
t(i) = poly(s((i + 1) / 2))
Next i
t(1) = String$(45 - Len(t(1)) - Len(t(3)), " ") & t(1)
t(2) = "/"
t(4) = "="
t(6) = "rem"
polyn = Join(t, " ")
End Function
Public Sub main()
Dim tests(7) As Variant
tests(1) = Array(Array(-42, 0, -12, 1), Array(-3, 1))
tests(2) = Array(Array(-3, 1), Array(-42, 0, -12, 1))
tests(3) = Array(Array(-42, 0, -12, 1), Array(-3, 1, 1))
tests(4) = Array(Array(2, 3, 1), Array(1, 1))
tests(5) = Array(Array(3, 5, 6, -4, 1), Array(1, 2, 1))
tests(6) = Array(Array(3, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 1), Array(1, 0, 0, 5, 0, 0, 0, 1))
tests(7) = Array(Array(-56, 87, -94, -55, 22, -7), Array(2, 0, 1))
Dim num As Variant, denom As Variant, quot As Variant, rmdr As Variant
For i = 1 To 7
num = tests(i)(1)
denom = tests(i)(2)
tmp = poly_div(num, denom)
quot = tmp(1)
rmdr = tmp(2)
Debug.Print polyn(Array(num, denom, quot, rmdr))
Next i
End Sub</syntaxhighlight>{{out}}
<pre> x3 - 12x2 - 42 / x - 3 = x2 - 9x - 27 rem -123
x - 3 / x3 - 12x2 - 42 = 0 rem x - 3
x3 - 12x2 - 42 / x2 + x - 3 = x - 13 rem 16x - 81
x2 + 3x + 2 / x + 1 = x + 2 rem 0
x4 - 4x3 + 6x2 + 5x + 3 / x2 + 2x + 1 = x2 - 6x + 17 rem -23x - 14
x11 + 3x8 + 7x2 + 3 / x7 + 5x3 + 1 = x4 + 3x - 5 rem -16x4 + 25x3 + 7x2 - 3x + 8
-7x5 + 22x4 - 55x3 - 94x2 + 87x - 56 / x2 + 2 = -7x3 + 22x2 - 41x - 138 rem 169x + 220 </pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
===Version 1===
{{libheader|Wren-dynamic}}
<syntaxhighlight lang="wren">import "./dynamic" for Tuple
 
var Solution = Tuple.create("Solution", ["quotient", "remainder"])
 
var polyDegree = Fn.new { |p|
for (i in p.count-1..0) if (p[i] != 0) return i
return -2.pow(31)
}
 
var polyShiftRight = Fn.new { |p, places|
if (places <= 0) return p
var pd = polyDegree.call(p)
if (pd + places >= p.count) {
Fiber.abort("The number of places to be shifted is too large.")
}
var d = p.toList
for (i in pd..0) {
d[i + places] = d[i]
d[i] = 0
}
return d
}
 
var polyMultiply = Fn.new { |p, m|
for (i in 0...p.count) p[i] = p[i] * m
}
 
var polySubtract = Fn.new { |p, s|
for (i in 0...p.count) p[i] = p[i] - s[i]
}
 
var polyLongDiv = Fn.new { |n, d|
if (n.count != d.count) {
Fiber.abort("Numerator and denominator vectors must have the same size")
}
var nd = polyDegree.call(n)
var dd = polyDegree.call(d)
if (dd < 0) {
Fiber.abort("Divisor must have at least one one-zero coefficient")
}
if (nd < dd) {
Fiber.abort("The degree of the divisor cannot exceed that of the numerator")
}
var n2 = n.toList
var q = List.filled(n.count, 0)
while (nd >= dd) {
var d2 = polyShiftRight.call(d, nd - dd)
q[nd - dd] = n2[nd] / d2[nd]
polyMultiply.call(d2, q[nd - dd])
polySubtract.call(n2, d2)
nd = polyDegree.call(n2)
}
return Solution.new(q, n2)
}
 
var polyShow = Fn.new { |p|
var pd = polyDegree.call(p)
for (i in pd..0) {
var coeff = p[i]
if (coeff != 0) {
System.write(
(coeff == 1) ? ((i < pd) ? " + " : "") :
(coeff == -1) ? ((i < pd) ? " - " : "-") :
(coeff < 0) ? ((i < pd) ? " - %(-coeff)" : "%(coeff)") :
((i < pd) ? " + %( coeff)" : "%(coeff)")
)
if (i > 1) {
System.write("x^%(i)")
} else if (i == 1) {
System.write("x")
}
}
}
System.print()
}
 
var n = [-42, 0, -12, 1]
var d = [ -3, 1, 0, 0]
System.write("Numerator : ")
polyShow.call(n)
System.write("Denominator : ")
polyShow.call(d)
System.print("-------------------------------------")
var sol = polyLongDiv.call(n, d)
System.write("Quotient : ")
polyShow.call(sol.quotient)
System.write("Remainder : ")
polyShow.call(sol.remainder)</syntaxhighlight>
 
{{out}}
<pre>
Numerator : x^3 - 12x^2 - 42
Denominator : x - 3
-------------------------------------
Quotient : x^2 - 9x - 27
Remainder : -123
</pre>
 
===Version 2===
<syntaxhighlight lang="wren">class Polynom {
construct new(factors) {
_factors = factors.toList
}
 
factors { _factors.toList }
 
/(divisor) {
var curr = canonical().factors
var right = divisor.canonical().factors
var result = []
var base = curr.count - right.count
while (base >= 0) {
var res = curr[-1] / right[-1]
result.add(res)
curr = curr[0...-1]
for (i in 0...right.count-1) {
curr[base + i] = curr[base + i] - res * right[i]
}
base = base - 1
}
var quot = Polynom.new(result[-1..0])
var rem = Polynom.new(curr).canonical()
return [quot, rem]
}
 
canonical() {
if (_factors[-1] != 0) return this
var newLen = factors.count
while (newLen > 0) {
if (_factors[newLen-1] != 0) return Polynom.new(_factors[0...newLen])
newLen = newLen - 1
}
return Polynom.new(_factors[0..0])
}
 
toString { "Polynomial(%(_factors.join(", ")))" }
}
 
var num = Polynom.new([-42, 0, -12, 1])
var den = Polynom.new([-3, 1, 0, 0])
var res = num / den
var quot = res[0]
var rem = res[1]
System.print("%(num) / %(den) = %(quot) remainder %(rem)")</syntaxhighlight>
 
{{out}}
<pre>
Polynomial(-42, 0, -12, 1) / Polynomial(-3, 1, 0, 0) = Polynomial(-27, -9, 1) remainder Polynomial(-123)
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn polyLongDivision(a,b){ // (a0 + a1x + a2x^2 + a3x^3 ...)
_assert_(degree(b)>=0,"degree(%s) < 0".fmt(b));
q:=List.createLong(a.len(),0.0);
Line 2,579 ⟶ 4,179:
if(str[0]=="+") str[1,*]; // leave leading space
else String("-",str[2,*]);
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">q,r:=polyLongDivision(T(-42.0, 0.0, -12.0, 1.0),T(-3.0, 1.0));
println("Quotient = ",polyString(q));
println("Remainder = ",polyString(r));</langsyntaxhighlight>
{{out}}
<pre>
2,442

edits