Many of the conversion functions are rounding or truncating operations. In this case, if the argument is a rational function, the result is the Euclidean quotient of the numerator by the denominator, and if the argument is a vector or a matrix, the operation is done componentwise. This will not be restated for every function.

Transforms the object x into a column vector. The dimension of the resulting vector can be optionally specified via the extra parameter n.

If n is omitted or 0, the dimension depends on the type of x; the vector has a single component, except when x is

***** a vector or a quadratic form (in which case the resulting vector
is simply the initial object considered as a row vector),

***** a polynomial or a power series. In the case of a polynomial, the
coefficients of the vector start with the leading coefficient of the
polynomial, while for power series only the significant coefficients are
taken into account, but this time by increasing order of degree.
In this last case, `Vec`

is the reciprocal function of `Pol`

and
`Ser`

respectively,

***** a matrix (the column of row vector comprising the matrix is returned),

***** a character string (a vector of individual characters is returned).

In the last two cases (matrix and character string), n is meaningless and must be omitted or an error is raised. Otherwise, if n is given, 0 entries are appended at the end of the vector if n > 0, and prepended at the beginning if n < 0. The dimension of the resulting vector is |n|.

See ??Vec for examples.

The library syntax is `GEN `

.
**gtocol0**(GEN x, long n)`GEN `

is also available.**gtocol**(GEN x)

As `Col`

(x, -n), then reverse the result. In particular,
`Colrev`

is the reciprocal function of `Polrev`

: the
coefficients of the vector start with the constant coefficient of the
polynomial and the others follow by increasing degree.

The library syntax is `GEN `

.
**gtocolrev0**(GEN x, long n)`GEN `

is also available.**gtocolrev**(GEN x)

Transforms a (row or column) vector x into a list, whose components are the entries of x. Similarly for a list, but rather useless in this case. For other types, creates a list with the single element x.

The library syntax is `GEN `

.
The variant **gtolist**(GEN x = NULL)`GEN `

creates an empty list.**mklist**(void)

A "Map" is an associative array, or dictionary: a data
type composed of a collection of (*key*, *value*) pairs, such that
each key appears just once in the collection. This function
converts the matrix [a_{1},b_{1};a_{2},b_{2};...;a_{n},b_{n}] to the map a_{i}`: — >`

b_{i}.

? M = Map(factor(13!)); ? mapget(M, 3) %2 = 5 ? P = Map(matreduce(primes([1,20]))) %3 = Map([2,1;3,1;5,1;7,1;11,1;13,1;17,1;19,1]) ? select(i->mapisdefined(P,i), [1..20]) %4 = [2, 3, 5, 7, 11, 13, 17, 19]

If the argument x is omitted, creates an empty map, which
may be filled later via `mapput`

.

The library syntax is `GEN `

.**gtomap**(GEN x = NULL)

Transforms the object x into a matrix.
If x is already a matrix, a copy of x is created.
If x is a row (resp. column) vector, this creates a 1-row (resp.
1-column) matrix, *unless* all elements are column (resp. row) vectors
of the same length, in which case the vectors are concatenated sideways
and the attached big matrix is returned.
If x is a binary quadratic form, creates the attached 2 x 2
matrix. Otherwise, this creates a 1 x 1 matrix containing x.

? Mat(x + 1) %1 = [x + 1] ? Vec( matid(3) ) %2 = [[1, 0, 0]~, [0, 1, 0]~, [0, 0, 1]~] ? Mat(%) %3 = [1 0 0] [0 1 0] [0 0 1] ? Col( [1,2; 3,4] ) %4 = [[1, 2], [3, 4]]~ ? Mat(%) %5 = [1 2] [3 4] ? Mat(Qfb(1,2,3)) %6 = [1 1] [1 3]

The library syntax is `GEN `

.**gtomat**(GEN x = NULL)

In its basic form, create an intmod or a polmod (a mod b); b must
be an integer or a polynomial. We then obtain a `t_INTMOD`

and a
`t_POLMOD`

respectively:

? t = Mod(2,17); t^8 %1 = Mod(1, 17) ? t = Mod(x,x^2+1); t^2 %2 = Mod(-1, x^2+1)

If a % b makes sense and yields a result of the
appropriate type (`t_INT`

or scalar/`t_POL`

), the operation succeeds as
well:

? Mod(1/2, 5) %3 = Mod(3, 5) ? Mod(7 + O(3^6), 3) %4 = Mod(1, 3) ? Mod(Mod(1,12), 9) %5 = Mod(1, 3) ? Mod(1/x, x^2+1) %6 = Mod(-x, x^2+1) ? Mod(exp(x), x^4) %7 = Mod(1/6*x^3 + 1/2*x^2 + x + 1, x^4)

If a is a complex object, "base change" it to ℤ/bℤ or K[x]/(b),
which is equivalent to, but faster than, multiplying it by `Mod(1,b)`

:

? Mod([1,2;3,4], 2) %8 = [Mod(1, 2) Mod(0, 2)] [Mod(1, 2) Mod(0, 2)] ? Mod(3*x+5, 2) %9 = Mod(1, 2)*x + Mod(1, 2) ? Mod(x^2 + y*x + y^3, y^2+1) %10 = Mod(1, y^2 + 1)*x^2 + Mod(y, y^2 + 1)*x + Mod(-y, y^2 + 1)

This function is not the same as x `%`

y, the result of which
has no knowledge of the intended modulus y. Compare

? x = 4 % 5; x + 1 %11 = 5 ? x = Mod(4,5); x + 1 %12 = Mod(0,5)

Note that such "modular" objects can be lifted via `lift`

or
`centerlift`

. The modulus of a `t_INTMOD`

or `t_POLMOD`

z can
be recovered via `z.mod`

.

The library syntax is `GEN `

.**gmodulo**(GEN a, GEN b)

Transforms the object t into a polynomial with main variable v. If t
is a scalar, this gives a constant polynomial. If t is a power series with
nonnegative valuation or a rational function, the effect is similar to
`truncate`

, i.e. we chop off the O(X^k) or compute the Euclidean
quotient of the numerator by the denominator, then change the main variable
of the result to v.

The main use of this function is when t is a vector: it creates the
polynomial whose coefficients are given by t, with t[1] being the leading
coefficient (which can be zero). It is much faster to evaluate
`Pol`

on a vector of coefficients in this way, than the corresponding
formal expression a_{n} X^n +...+ a_{0}, which is evaluated naively exactly
as written (linear versus quadratic time in n). `Polrev`

can be used if
one wants x[1] to be the constant coefficient:

? Pol([1,2,3]) %1 = x^2 + 2*x + 3 ? Polrev([1,2,3]) %2 = 3*x^2 + 2*x + 1

The reciprocal function of `Pol`

(resp. `Polrev`

) is `Vec`

(resp.
`Vecrev`

).

? Vec(Pol([1,2,3])) %1 = [1, 2, 3] ? Vecrev( Polrev([1,2,3]) ) %2 = [1, 2, 3]

**Warning.** This is *not* a substitution function. It will not
transform an object containing variables of higher priority than v.

? Pol(x + y, y) *** at top-level: Pol(x+y,y) *** ^ — — — - *** Pol: variable must have higher priority in gtopoly.

The library syntax is `GEN `

where **gtopoly**(GEN t, long v = -1)`v`

is a variable number.

Transform the object t into a polynomial
with main variable v. If t is a scalar, this gives a constant polynomial.
If t is a power series, the effect is identical to `truncate`

, i.e. it
chops off the O(X^k).

The main use of this function is when t is a vector: it creates the
polynomial whose coefficients are given by t, with t[1] being the
constant term. `Pol`

can be used if one wants t[1] to be the leading
coefficient:

? Polrev([1,2,3]) %1 = 3*x^2 + 2*x + 1 ? Pol([1,2,3]) %2 = x^2 + 2*x + 3

The reciprocal function of `Pol`

(resp. `Polrev`

) is `Vec`

(resp.
`Vecrev`

).

The library syntax is `GEN `

where **gtopolyrev**(GEN t, long v = -1)`v`

is a variable number.

Creates the binary quadratic form ax^2+bxy+cy^2. Negative definite forms are not implemented, use their positive definite counterpart instead. The syntax Qfb([a,b,c]) is also accepted.

The library syntax is `GEN `

.**Qfb0**(GEN a, GEN b = NULL, GEN c = NULL)

Transforms the object s into a power series with main variable v
(x by default) and precision (number of significant terms) equal to
d ≥ 0 (d = `seriesprecision`

by default). If s is a
scalar, this gives a constant power series in v with precision `d`

.
If s is a polynomial, the polynomial is truncated to d terms if needed

? \ps seriesprecision = 16 significant terms ? Ser(1) \\ 16 terms by default %1 = 1 + O(x^16) ? Ser(1, 'y, 5) %2 = 1 + O(y^5) ? Ser(x^2,, 5) %3 = x^2 + O(x^7) ? T = polcyclo(100) %4 = x^40 - x^30 + x^20 - x^10 + 1 ? Ser(T, 'x, 11) %5 = 1 - x^10 + O(x^11)

The function is more or less equivalent with multiplication by 1 + O(v^d) in theses cases, only faster.

For the remaining types, vectors and power series, we first explain what occurs if d is omitted. In this case, the function uses exactly the amount of information given in the input:

***** If s is already a power series in v, we return it verbatim;

***** If s is a vector, the coefficients of the vector are
understood to be the coefficients of the power series starting from the
constant term (as in `Polrev`

(x)); in other words we convert
`t_VEC`

/ `t_COL`

to the power series whose significant terms are exactly
given by the vector entries.

On the other hand, if d is explicitly given, we abide by its value and return a series, truncated or extended with zeros as needed, with d significant terms.

? v = [1,2,3]; ? Ser(v, t) \\ 3 terms: seriesprecision is ignored! %7 = 1 + 2*t + 3*t^2 + O(t^3) ? Ser(v, t, 7) \\ 7 terms as explicitly requested %8 = 1 + 2*t + 3*t^2 + O(t^7) ? s = 1+x+O(x^2); ? Ser(s) %10 = 1 + x + O(x^2) \\ 2 terms: seriesprecision is ignored ? Ser(s, x, 7) \\ extend to 7 terms %11 = 1 + x + O(x^7) ? Ser(s, x, 1) \\ truncate to 1 term %12 = 1 + O(x)

The warning given for `Pol`

also applies here: this is not a substitution
function.

The library syntax is `GEN `

where **Ser0**(GEN s, long v = -1, GEN d = NULL, long precdl)`v`

is a variable number.

Converts x into a set, i.e. into a row vector, with strictly increasing
entries with respect to the (somewhat arbitrary) universal comparison function
`cmp`

. Standard container types `t_VEC`

, `t_COL`

, `t_LIST`

and
`t_VECSMALL`

are converted to the set with corresponding elements. All
others are converted to a set with one element.

? Set([1,2,4,2,1,3]) %1 = [1, 2, 3, 4] ? Set(x) %2 = [x] ? Set(Vecsmall([1,3,2,1,3])) %3 = [1, 2, 3]

The library syntax is `GEN `

.**gtoset**(GEN x = NULL)

Converts its argument list into a
single character string (type `t_STR`

, the empty string if x is omitted).
To recover an ordinary `GEN`

from a string, apply `eval`

to it. The
arguments of `Str`

are evaluated in string context, see Section se:strings.

? x2 = 0; i = 2; Str(x, i) %1 = "x2" ? eval(%) %2 = 0

This function is mostly useless in library mode. Use the pair
`strtoGEN`

/`GENtostr`

to convert between `GEN`

and `char*`

.
The latter returns a malloced string, which should be freed after usage.

The library syntax is `GEN `

.**Str**(GEN vec_{x})

Transforms the object x into a row vector. The dimension of the resulting vector can be optionally specified via the extra parameter n. If n is omitted or 0, the dimension depends on the type of x; the vector has a single component, except when x is

***** a vector or a quadratic form: returns the initial object considered as a
row vector,

***** a polynomial or a power series: returns a vector consisting of the
coefficients. In the case of a polynomial, the coefficients of the vector
start with the leading coefficient of the polynomial, while for power series
only the significant coefficients are taken into account, but this time by
increasing order of degree. In particular the valuation is ignored
(which makes the function useful for series of negative valuation):

? Vec(3*x^2 + x) %1 = [3, 1, 0] ? Vec(x^2 + 3*x^3 + O(x^5)) %2 = [1, 3, 0] ? Vec(x^-2 + 3*x^-1 + O(x)) %3 = [1, 3, 0]

`Vec`

is the reciprocal function of `Pol`

for a
polynomial and of `Ser`

for power series of valuation 0.

***** a matrix: returns the vector of columns comprising the matrix,

? m = [1,2,3;4,5,6] %4 = [1 2 3] [4 5 6] ? Vec(m) %5 = [[1, 4]~, [2, 5]~, [3, 6]~]

***** a character string: returns the vector of individual characters,

? Vec("PARI") %6 = ["P", "A", "R", "I"]

***** a map: returns the vector of the domain of the map,

***** an error context (`t_ERROR`

): returns the error components, see
`iferr`

.

In the last four cases (matrix, character string, map, error), n is meaningless and must be omitted or an error is raised. Otherwise, if n is given, 0 entries are appended at the end of the vector if n > 0, and prepended at the beginning if n < 0. The dimension of the resulting vector is |n|. This allows to write a conversion function for series that takes positive valuations into account:

? serVec(s) = Vec(s, -serprec(s,variable(s))); ? Vec(x^2 + 3*x^3 + O(x^5)) %2 = [0, 0, 1, 3, 0]

(That function is not intended for series of negative valuation.)

The library syntax is `GEN `

.
**gtovec0**(GEN x, long n)`GEN `

is also available.**gtovec**(GEN x)

As `Vec`

(x, -n), then reverse the result. In particular,
`Vecrev`

is the reciprocal function of `Polrev`

: the
coefficients of the vector start with the constant coefficient of the
polynomial and the others follow by increasing degree.

The library syntax is `GEN `

.
**gtovecrev0**(GEN x, long n)`GEN `

is also available.**gtovecrev**(GEN x)

Transforms the object x into a row vector of type `t_VECSMALL`

. The
dimension of the resulting vector can be optionally specified via the extra
parameter n.

This acts as `Vec`

(x,n), but only on a limited set of objects:
the result must be representable as a vector of small integers.
If x is a character string, a vector of individual characters in ASCII
encoding is returned (`strchr`

yields back the character string).

The library syntax is `GEN `

.
**gtovecsmall0**(GEN x, long n)`GEN `

is also available.**gtovecsmall**(GEN x)

Outputs the vector of the binary digits of |x|. Here x can be an integer, a real number (in which case the result has two components, one for the integer part, one for the fractional part) or a vector/matrix.

? binary(10) %1 = [1, 0, 1, 0] ? binary(3.14) %2 = [[1, 1], [0, 0, 1, 0, 0, 0, [...]] ? binary([1,2]) %3 = [[1], [1, 0]]

For integer x ≥ 1, the number of bits is
`logint`

(x,2) + 1. By convention, 0 has no digits:

? binary(0) %4 = []

The library syntax is `GEN `

.**binaire**(GEN x)

Bitwise `and`

of two integers x and y, that is the integer
∑_{i} (x_{i} `and`

y_{i}) 2^i

Negative numbers behave 2-adically, i.e. the result is the 2-adic limit
of `bitand`

(x_{n},y_{n}), where x_{n} and y_{n} are nonnegative integers
tending to x and y respectively. (The result is an ordinary integer,
possibly negative.)

? bitand(5, 3) %1 = 1 ? bitand(-5, 3) %2 = 3 ? bitand(-5, -3) %3 = -7

The library syntax is `GEN `

.
Also available is
**gbitand**(GEN x, GEN y)`GEN `

, which returns the bitwise **ibitand**(GEN x, GEN y)*and*
of |x| and |y|, two integers.

bitwise negation of an integer x,
truncated to n bits, n ≥ 0, that is the integer
∑_{i = 0}^{n-1} `not`

(x_{i}) 2^i.
The special case n = -1 means no truncation: an infinite sequence of
leading 1 is then represented as a negative number.

See Section se:bitand for the behavior for negative arguments.

The library syntax is `GEN `

.**gbitneg**(GEN x, long n)

Bitwise negated imply of two integers x and
y (or `not`

(x ==> y)), that is the integer ∑
(x_{i} `and not`

(y_{i})) 2^i

See Section se:bitand for the behavior for negative arguments.

The library syntax is `GEN `

.
Also available is
**gbitnegimply**(GEN x, GEN y)`GEN `

, which returns the bitwise negated
imply of |x| and |y|, two integers.**ibitnegimply**(GEN x, GEN y)

bitwise (inclusive)
`or`

of two integers x and y, that is the integer ∑
(x_{i} `or`

y_{i}) 2^i

See Section se:bitand for the behavior for negative arguments.

The library syntax is `GEN `

.
Also available is
**gbitor**(GEN x, GEN y)`GEN `

, which returns the bitwise **ibitor**(GEN x, GEN y)*or*
of |x| and |y|, two integers.

The function behaves differently according to whether n is present or not. If n is missing, the function returns the (floating point) precision in bits of the PARI object x.

If x is an exact object, the function returns `+oo`

.

? bitprecision(exp(1e-100)) %1 = 512 \\ 512 bits ? bitprecision( [ exp(1e-100), 0.5 ] ) %2 = 128 \\ minimal accuracy among components ? bitprecision(2 + x) %3 = +oo \\ exact object

Use `getlocalbitprec()`

to retrieve the
working bit precision (as modified by possible `localbitprec`

statements).

If n is present and positive, the function creates a new object equal to x with the new bit-precision roughly n. In fact, the smallest multiple of 64 (resp. 32 on a 32-bit machine) larger than or equal to n.

For x a vector or a matrix, the operation is
done componentwise; for series and polynomials, the operation is done
coefficientwise. For real x, n is the number of desired significant
*bits*. If n is smaller than the precision of x, x is truncated,
otherwise x is extended with zeros. For exact or non-floating-point types,
no change.

? bitprecision(Pi, 10) \\ actually 64 bits ~ 19 decimal digits %1 = 3.141592653589793239 ? bitprecision(1, 10) %2 = 1 ? bitprecision(1 + O(x), 10) %3 = 1 + O(x) ? bitprecision(2 + O(3^5), 10) %4 = 2 + O(3^5)

The library syntax is `GEN `

.**bitprecision00**(GEN x, GEN n = NULL)

Outputs the n-th bit of x starting
from the right (i.e. the coefficient of 2^n in the binary expansion of x).
The result is 0 or 1. For x ≥ 1, the highest 1-bit is at n =
`logint`

(x) (and bigger n gives 0).

? bittest(7, 0) %1 = 1 \\ the bit 0 is 1 ? bittest(7, 2) %2 = 1 \\ the bit 2 is 1 ? bittest(7, 3) %3 = 0 \\ the bit 3 is 0

See Section se:bitand for the behavior at negative arguments.

The library syntax is `GEN `

.
For a **gbittest**(GEN x, long n)`t_INT`

x, the variant `long `

is
generally easier to use, and if furthermore n ≥ 0 the low-level function
**bittest**(GEN x, long n)`ulong `

returns **int_bit**(GEN x, long n)`bittest(abs(x),n)`

.

Bitwise (exclusive) `or`

of two integers x and y, that is the integer
∑ (x_{i} `xor`

y_{i}) 2^i

See Section se:bitand for the behavior for negative arguments.

The library syntax is `GEN `

.
Also available is
**gbitxor**(GEN x, GEN y)`GEN `

, which returns the bitwise **ibitxor**(GEN x, GEN y)*xor*
of |x| and |y|, two integers.

Ceiling of x. When x is in ℝ, the result is the
smallest integer greater than or equal to x. Applied to a rational
function, `ceil`

(x) returns the Euclidean quotient of the numerator by
the denominator.

The library syntax is `GEN `

.**gceil**(GEN x)

Same as `lift`

, except that `t_INTMOD`

and `t_PADIC`

components
are lifted using centered residues:

***** for a `t_INTMOD`

x ∈ ℤ/nℤ, the lift y is such that
-n/2 < y ≤ n/2.

***** a `t_PADIC`

x is lifted in the same way as above (modulo
p^`padicprec(x)`

) if its valuation v is nonnegative; if not, returns
the fraction p^v `centerlift`

(x p^{-v}); in particular, rational
reconstruction is not attempted. Use `bestappr`

for this.

For backward compatibility, `centerlift(x,'v)`

is allowed as an alias
for `lift(x,'v)`

.

The library syntax is

.**centerlift**(GEN x)

Returns the characteristic of the base ring over which x is defined (as
defined by `t_INTMOD`

and `t_FFELT`

components). The function raises an
exception if incompatible primes arise from `t_FFELT`

and `t_PADIC`

components.

? characteristic(Mod(1,24)*x + Mod(1,18)*y) %1 = 6

The library syntax is `GEN `

.**characteristic**(GEN x)

Extracts the n-th-component of x. This is to be understood as follows: every PARI type has one or two initial code words. The components are counted, starting at 1, after these code words. In particular if x is a vector, this is indeed the n-th-component of x, if x is a matrix, the n-th column, if x is a polynomial, the n-th coefficient (i.e. of degree n-1), and for power series, the n-th significant coefficient.

For polynomials and power series, one should rather use `polcoef`

, and
for vectors and matrices, the `[]`

operator. Namely, if x is a
vector, then `x[n]`

represents the n-th component of x. If
x is a matrix, `x[m,n]`

represents the coefficient of row `m`

and
column `n`

of the matrix, `x[m,]`

represents the m-th
*row* of x, and `x[,n]`

represents the n-th
*column* of x.

Using of this function requires detailed knowledge of the structure of the different PARI types, and thus it should almost never be used directly. Some useful exceptions:

? x = 3 + O(3^5); ? component(x, 2) %2 = 81 \\ p^(p-adic accuracy) ? component(x, 1) %3 = 3 \\ p ? q = Qfb(1,2,3); ? component(q, 1) %5 = 1

The library syntax is `GEN `

.**compo**(GEN x, long n)

Conjugate of x. The meaning of this
is clear, except that for real quadratic numbers, it means conjugation in the
real quadratic field. This function has no effect on integers, reals,
intmods, fractions or p-adics. The only forbidden type is polmod
(see `conjvec`

for this).

The library syntax is `GEN `

.**gconj**(GEN x)

Conjugate vector representation of z. If z is a
polmod, equal to `Mod`

(a,T), this gives a vector of length
degree(T) containing:

***** the complex embeddings of z if T has rational coefficients,
i.e. the a(r[i]) where r = `polroots`

(T);

***** the conjugates of z if T has some intmod coefficients;

if z is a finite field element, the result is the vector of
conjugates [z,z^p,z^{p^2},...,z^{p^{n-1}}] where n = degree(T).

If z is an integer or a rational number, the result is z. If z is a (row or column) vector, the result is a matrix whose columns are the conjugate vectors of the individual elements of z.

The library syntax is `GEN `

.**conjvec**(GEN z, long prec)

Denominator of f. The meaning of this is clear when f is a rational number or function. If f is an integer or a polynomial, it is treated as a rational number or function, respectively, and the result is equal to 1. For polynomials, you probably want to use

denominator( content(f) )

instead. As for modular objects, `t_INTMOD`

and `t_PADIC`

have denominator 1, and the denominator of a `t_POLMOD`

is the
denominator of its lift.

If f is a recursive structure, for instance a vector or matrix, the lcm
of the denominators of its components (a common denominator) is computed.
This also applies for `t_COMPLEX`

s and `t_QUAD`

s.

**Warning.** Multivariate objects are created according to variable
priorities, with possibly surprising side effects (x/y is a polynomial, but
y/x is a rational function). See Section se:priority.

The optional argument D allows to control over which ring we compute the denominator and get a more predictable behaviour:

***** 1: we only consider the underlying ℚ-structure and the
denominator is a (positive) rational integer

***** a simple variable, say `'x`

: all entries as rational functions
in K(x) and the denominator is a polynomial in x.

? f = x + 1/y + 1/2; ? denominator(f) \\ a t_POL in x %2 = 1 ? denominator(f, 1) \\ Q-denominator %3 = 2 ? denominator(f, x) \\ as a t_POL in x, seen above %4 = 1 ? denominator(f, y) \\ as a rational function in y %5 = 2*y

The library syntax is `GEN `

.
Also available are
**denominator**(GEN f, GEN D = NULL)`GEN `

which implements the not very useful default
behaviour (D is **denom**(GEN x)`NULL`

) and `GEN `

(D = 1).**Q_denom**(GEN x)

Outputs the vector of the digits of |x| in base b, where x and b are
integers (b = 10 by default), from most significant down to least
significant. For x ≥ 1, the number of digits is
`logint`

(x,b) + 1. See `fromdigits`

for the reverse operation.

We also allow x an integral p-adic in which case b should be omitted or equal to p. Digits are still ordered from most significant to least significant in the p-adic sense (meaning we start from x mod p); trailing zeros are truncated.

? digits(1230) %1 = [1, 2, 3, 0] ? digits(10, 2) \\ base 2 %2 = [1, 0, 1, 0]

By convention, 0 has no digits:

? digits(0) %3 = [] ? 1105 + O(5^5) %4 = 5 + 4*5^2 + 3*5^3 + O(5^5) ? digits(%) %5 = [0, 1, 4, 3]

The library syntax is `GEN `

.**digits**(GEN x, GEN b = NULL)

When x is a `t_REAL`

, the result is the binary exponent e of x.
For a nonzero x, this is the unique integer e such that
2^e ≤ |x| < 2^{e+1}. For a real 0, this returns the PARI exponent e
attached to x (which may represent any floating-point number less than
2^e in absolute value).

? exponent(Pi) %1 = 1 ? exponent(4.0) %2 = 2 ? exponent(0.0) %3 = -128 ? default(realbitprecision) %4 = 128

This definition extends naturally to nonzero integers,
and the exponent of an exact 0 is -`oo`

by convention.

For convenience, we *define* the exponent of a `t_FRAC`

a/b as
the difference of `exponent`

(a) and `exponent`

(b); note that,
if e' denotes the exponent of `a/b * 1.0`

, then the exponent e
we return is either e' or e'+1, thus 2^{e+1} is an upper bound for
|a/b|.

? [ exponent(9), exponent(10), exponent(9/10), exponent(9/10*1.) ] %5 = [3, 3, 0, -1]

For a PARI object of type `t_COMPLEX`

, `t_POL`

, `t_SER`

, `t_VEC`

,
`t_COL`

, `t_MAT`

this returns the largest exponent found among the
components of x. Hence 2^{e+1} is a quick upper bound for the sup norm
of real matrices or polynomials; and 2^{e+(3/2)} for complex ones.

? exponent(3*x^2 + 15*x - 100) %5 = 6 ? exponent(0) %6 = -oo

The library syntax is `GEN `

.**gpexponent**(GEN x)

Floor of x. When x is in ℝ, the result is the
largest integer smaller than or equal to x. Applied to a rational function,
`floor`

(x) returns the Euclidean quotient of the numerator by the
denominator.

The library syntax is `GEN `

.**gfloor**(GEN x)

Fractional part of x. Identical to x-floor(x). If x is real, the result is in [0,1[.

The library syntax is `GEN `

.**gfrac**(GEN x)

Gives the integer formed by the elements of x seen as the digits of a
number in base b (b = 10 by default); b must be an integer satisfying
|b| > 1. This is the reverse of `digits`

:

? digits(1234, 5) %1 = [1,4,4,1,4] ? fromdigits([1,4,4,1,4],5) %2 = 1234

By convention, 0 has no digits:

? fromdigits([]) %3 = 0

This function works with x a `t_VECSMALL`

; and
also with b < 0 or x[i] not an actual digit in base b (i.e.,
x[i] < 0 or x[i] ≥ b): if x has length n, we return
∑_{i = 1}^n x[i] b^{n-i}.

The library syntax is `GEN `

.**fromdigits**(GEN x, GEN b = NULL)

Imaginary part of x. When x is a quadratic number, this is the coefficient of ω in the "canonical" integral basis (1,ω).

? imag(3 + I) %1 = 1 ? x = 3 + quadgen(-23); ? imag(x) \\ as a quadratic number %3 = 1 ? imag(x * 1.) \\ as a complex number %4 = 2.3979157616563597707987190320813469600

The library syntax is `GEN `

.**gimag**(GEN x)

Length of x; `#`

x is a shortcut for `length`

(x).
This is mostly useful for

***** vectors: dimension (0 for empty vectors),

***** lists: number of entries (0 for empty lists),

***** maps: number of entries (0 for empty maps),

***** matrices: number of columns,

***** character strings: number of actual characters (without
trailing `\0`

, should you expect it from C `char*`

).

? #"a string" %1 = 8 ? #[3,2,1] %2 = 3 ? #[] %3 = 0 ? #matrix(2,5) %4 = 5 ? L = List([1,2,3,4]); #L %5 = 4 ? M = Map([a,b; c,d; e,f]); #M %6 = 3

The routine is in fact defined for arbitrary GP types, but is awkward and
useless in other cases: it returns the number of non-code words in x, e.g.
the effective length minus 2 for integers since the `t_INT`

type has two code
words.

The library syntax is `long `

.**glength**(GEN x)

If v is omitted, lifts intmods from ℤ/nℤ in ℤ,
p-adics from ℚ_{p} to ℚ (as `truncate`

), and polmods to
polynomials. Otherwise, lifts only polmods whose modulus has main
variable v. `t_FFELT`

are not lifted, nor are List elements: you may
convert the latter to vectors first, or use `apply(lift,L)`

. More
generally, components for which such lifts are meaningless (e.g. character
strings) are copied verbatim.

? lift(Mod(5,3)) %1 = 2 ? lift(3 + O(3^9)) %2 = 3 ? lift(Mod(x,x^2+1)) %3 = x ? lift(Mod(x,x^2+1)) %4 = x

Lifts are performed recursively on an object components, but only
by *one level*: once a `t_POLMOD`

is lifted, the components of
the result are *not* lifted further.

? lift(x * Mod(1,3) + Mod(2,3)) %4 = x + 2 ? lift(x * Mod(y,y^2+1) + Mod(2,3)) %5 = y*x + Mod(2, 3) \\ do you understand this one? ? lift(x * Mod(y,y^2+1) + Mod(2,3), 'x) %6 = Mod(y, y^2 + 1)*x + Mod(Mod(2, 3), y^2 + 1) ? lift(%, y) %7 = y*x + Mod(2, 3)

To recursively lift all components not only by one level,
but as long as possible, use `liftall`

. To lift only `t_INTMOD`

s and
`t_PADIC`

s components, use `liftint`

. To lift only `t_POLMOD`

s
components, use `liftpol`

. Finally, `centerlift`

allows to lift
`t_INTMOD`

s and `t_PADIC`

s using centered residues (lift of smallest
absolute value).

The library syntax is `GEN `

where **lift0**(GEN x, long v = -1)`v`

is a variable number.
Also available is `GEN `

corresponding to
**lift**(GEN x)`lift0(x,-1)`

.

Recursively lift all components of x from ℤ/nℤ to ℤ,
from ℚ_{p} to ℚ (as `truncate`

), and polmods to
polynomials. `t_FFELT`

are not lifted, nor are List elements: you may
convert the latter to vectors first, or use `apply(liftall,L)`

. More
generally, components for which such lifts are meaningless (e.g. character
strings) are copied verbatim.

? liftall(x * (1 + O(3)) + Mod(2,3)) %1 = x + 2 ? liftall(x * Mod(y,y^2+1) + Mod(2,3)*Mod(z,z^2)) %2 = y*x + 2*z

The library syntax is `GEN `

.**liftall**(GEN x)

Recursively lift all components of x from ℤ/nℤ to ℤ and
from ℚ_{p} to ℚ (as `truncate`

).
`t_FFELT`

are not lifted, nor are List elements: you may
convert the latter to vectors first, or use `apply(liftint,L)`

. More
generally, components for which such lifts are meaningless (e.g. character
strings) are copied verbatim.

? liftint(x * (1 + O(3)) + Mod(2,3)) %1 = x + 2 ? liftint(x * Mod(y,y^2+1) + Mod(2,3)*Mod(z,z^2)) %2 = Mod(y, y^2 + 1)*x + Mod(Mod(2*z, z^2), y^2 + 1)

The library syntax is `GEN `

.**liftint**(GEN x)

Recursively lift all components of x which are polmods to
polynomials. `t_FFELT`

are not lifted, nor are List elements: you may
convert the latter to vectors first, or use `apply(liftpol,L)`

. More
generally, components for which such lifts are meaningless (e.g. character
strings) are copied verbatim.

? liftpol(x * (1 + O(3)) + Mod(2,3)) %1 = (1 + O(3))*x + Mod(2, 3) ? liftpol(x * Mod(y,y^2+1) + Mod(2,3)*Mod(z,z^2)) %2 = y*x + Mod(2, 3)*z

The library syntax is `GEN `

.**liftpol**(GEN x)

Algebraic norm of x, i.e. the product of x with
its conjugate (no square roots are taken), or conjugates for polmods. For
vectors and matrices, the norm is taken componentwise and hence is not the
L^2-norm (see `norml2`

). Note that the norm of an element of
ℝ is its square, so as to be compatible with the complex norm.

The library syntax is `GEN `

.**gnorm**(GEN x)

Numerator of f. This is defined as `f * denominator(f,D)`

, see
`denominator`

for details. The optional argument D allows to control
over which ring we compute the denominator:

***** 1: we only consider the underlying ℚ-structure and the
denominator is a (positive) rational integer

***** a simple variable, say `'x`

: all entries as rational functions
in K(x) and the denominator is a polynomial in x.

? f = x + 1/y + 1/2; ? numerator(f) \\ a t_POL in x %2 = x + ((y + 2)/(2*y)) ? numerator(f, 1) \\ Q-denominator is 2 %3 = x + ((y + 2)/y) ? numerator(f, y) \\ as a rational function in y %5 = 2*y*x + (y + 2)

The library syntax is `GEN `

.
Also available are
**numerator**(GEN f, GEN D = NULL)`GEN `

which implements the not very useful default
behaviour (D is **numer**(GEN x)`NULL`

) and
`GEN `

(D = 1) and also returns the
denominator (coding 1 as **Q_remove_denom**(GEN x, GEN *ptd)`NULL`

).

Returns an object meaning + oo , for use in functions such as
`intnum`

. It can be negated (`-oo`

represents - oo ), and
compared to real numbers (`t_INT`

, `t_FRAC`

, `t_REAL`

), with the
expected meaning: + oo is greater than any real number and - oo is
smaller.

The library syntax is `GEN `

.**mkoo**()

Returns the absolute p-adic precision of the object x; this is the
minimum precision of the components of x. The result is `+oo`

if x
is an exact object (as a p-adic):

? padicprec((1 + O(2^5)) * x + (2 + O(2^4)), 2) %1 = 4 ? padicprec(x + 2, 2) %2 = +oo ? padicprec(2 + x + O(x^2), 2) %3 = +oo

The function raises an exception if it encounters an object incompatible with p-adic computations:

? padicprec(O(3), 2) *** at top-level: padicprec(O(3),2) *** ^ — — — — — -- *** padicprec: inconsistent moduli in padicprec: 3 != 2 ? padicprec(1.0, 2) *** at top-level: padicprec(1.0,2) *** ^ — — — — — - *** padicprec: incorrect type in padicprec (t_REAL).

The library syntax is `GEN `

.
Also available is the function **gppadicprec**(GEN x, GEN p)`long `

,
which returns **padicprec**(GEN x, GEN p)`LONG_MAX`

if x = 0 and the p-adic precision as a
`long`

integer.

The function behaves differently according to whether n is
present or not. If n is missing, the function returns
the floating point precision in decimal digits of the PARI object x. If x
has no floating point component, the function returns `+oo`

.

? precision(exp(1e-100)) %1 = 154 \\ 154 significant decimal digits ? precision(2 + x) %2 = +oo \\ exact object ? precision(0.5 + O(x)) %3 = 38 \\ floating point accuracy, NOT series precision ? precision( [ exp(1e-100), 0.5 ] ) %4 = 38 \\ minimal accuracy among components

Using `getlocalprec()`

allows to retrieve
the working precision (as modified by possible `localprec`

statements).

If n is present, the function creates a new object equal to x with a new
floating point precision n: n is the number of desired significant
*decimal* digits. If n is smaller than the precision of a `t_REAL`

component of x, it is truncated, otherwise it is extended with zeros.
For non-floating-point types, no change.

The library syntax is `GEN `

.
Also available are **precision00**(GEN x, GEN n = NULL)`GEN `

and
**gprec**(GEN x, long n)`long `

. In both, the accuracy is expressed in
**precision**(GEN x)*words* (32-bit or 64-bit depending on the architecture).

Returns a random element in various natural sets depending on the argument N.

***** `t_INT`

: let n = |N|-1; if N > 0 returns an integer uniformly
distributed in [0, n]; if N < 0 returns an integer uniformly
distributed in [-n, n]. Omitting the argument is
equivalent to `random(2^31)`

.

***** `t_REAL`

: returns a real number in [0,1[ with the same accuracy as
N (whose mantissa has the same number of significant words).

***** `t_INTMOD`

: returns a random intmod for the same modulus.

***** `t_FFELT`

: returns a random element in the same finite field.

***** `t_VEC`

of length 2, N = [a,b]: returns an integer uniformly
distributed between a and b.

***** `t_VEC`

generated by `ellinit`

over a finite field k
(coefficients are `t_INTMOD`

s modulo a prime or `t_FFELT`

s): returns a
"random" k-rational *affine* point on the curve. More precisely
if the curve has a single point (at infinity!) we return it; otherwise
we return an affine point by drawing an abscissa uniformly at
random until `ellordinate`

succeeds. Note that this is definitely not a
uniform distribution over E(k), but it should be good enough for
applications.

***** `t_POL`

return a random polynomial of degree at most the degree of N.
The coefficients are drawn by applying `random`

to the leading
coefficient of N.

? random(10) %1 = 9 ? random(Mod(0,7)) %2 = Mod(1, 7) ? a = ffgen(ffinit(3,7), 'a); random(a) %3 = a^6 + 2*a^5 + a^4 + a^3 + a^2 + 2*a ? E = ellinit([3,7]*Mod(1,109)); random(E) %4 = [Mod(103, 109), Mod(10, 109)] ? E = ellinit([1,7]*a^0); random(E) %5 = [a^6 + a^5 + 2*a^4 + 2*a^2, 2*a^6 + 2*a^4 + 2*a^3 + a^2 + 2*a] ? random(Mod(1,7)*x^4) %6 = Mod(5, 7)*x^4 + Mod(6, 7)*x^3 + Mod(2, 7)*x^2 + Mod(2, 7)*x + Mod(5, 7)

These variants all depend on a single internal generator, and are
independent from your operating system's random number generators.
A random seed may be obtained via `getrand`

, and reset
using `setrand`

: from a given seed, and given sequence of `random`

s,
the exact same values will be generated. The same seed is used at each
startup, reseed the generator yourself if this is a problem. Note that
internal functions also call the random number generator; adding such a
function call in the middle of your code will change the numbers produced.

**Technical note.**
Up to
version 2.4 included, the internal generator produced pseudo-random numbers
by means of linear congruences, which were not well distributed in arithmetic
progressions. We now
use Brent's XORGEN algorithm, based on Feedback Shift Registers, see
`http://wwwmaths.anu.edu.au/~brent/random.html`

. The generator has period
2^{4096}-1, passes the Crush battery of statistical tests of L'Ecuyer and
Simard, but is not suitable for cryptographic purposes: one can reconstruct
the state vector from a small sample of consecutive values, thus predicting
the entire sequence.

**Parallelism.** In multi-threaded programs, each thread has a
separate generator. They all start in the same `setrand(1)`

state, so
will all produce the same sequence of pseudo-random numbers although
the various states are not shared. To avoid this, use `setrand`

to
provide a different starting state to each thread:

\\ with 8 threads ? parvector(8, i, random()) \\ all 8 threads return the same number %1 = [1546275796, 1546275796, ... , 1546275796] ? parvector(8, i, random()) \\ ... and again since they are restarted %2 = [1546275796, 1546275796, ... , 1546275796] ? s = [1..8]; \\ 8 random seeds; we could use vector(8,i,random()) ? parvector(8, i, setrand(s[i]); random()) \\ now we get 8 different numbers

The library syntax is `GEN `

.**genrand**(GEN N = NULL)

Also available: `GEN `

and **ellrandom**(GEN E)`GEN `

.**ffrandom**(GEN a)

Real part of x. When x is a quadratic number, this is the coefficient of 1 in the "canonical" integral basis (1,ω).

? real(3 + I) %1 = 3 ? x = 3 + quadgen(-23); ? real(x) \\ as a quadratic number %3 = 3 ? real(x * 1.) \\ as a complex number %4 = 3.5000000000000000000000000000000000000

The library syntax is `GEN `

.**greal**(GEN x)

If x is in ℝ, rounds x to the nearest integer (rounding to + oo in case of ties), then sets e to the number of error bits, that is the binary exponent of the difference between the original and the rounded value (the "fractional part"). If the exponent of x is too large compared to its precision (i.e. e > 0), the result is undefined and an error occurs if e was not given.

**Important remark.** Contrary to the other truncation functions,
this function operates on every coefficient at every level of a PARI object.
For example
truncate((2.4*X^2-1.7)/(X)) = 2.4*X,
whereas
round((2.4*X^2-1.7)/(X)) = (2*X^2-2)/(X).
An important use of `round`

is to get exact results after an approximate
computation, when theory tells you that the coefficients must be integers.

The library syntax is `GEN `

.
Also available are **round0**(GEN x, GEN *e = NULL)`GEN `

and
**grndtoi**(GEN x, long *e)`GEN `

.**ground**(GEN x)

Remove all terms of degree strictly less than n in series s. When the series contains no terms of degree < n, return O(x^n).

? s = 1/x + x + 2*x^2 + O(x^3); ? serchop(s) %2 = x + 2*x^3 + O(x^3) ? serchop(s, 2) %3 = 2*x^2 + O(x^3) ? serchop(s, 100) %4 = O(x^100)

The library syntax is `GEN `

.**serchop**(GEN s, long n)

Returns the absolute precision of x with respect to power series
in the variable v; this is the
minimum precision of the components of x. The result is `+oo`

if x
is an exact object (as a series in v):

? serprec(x + O(y^2), y) %1 = 2 ? serprec(x + 2, x) %2 = +oo ? serprec(2 + x + O(x^2), y) %3 = +oo

The library syntax is `GEN `

where **gpserprec**(GEN x, long v)`v`

is a variable number.
Also available is `long `

, which returns
**serprec**(GEN x, GEN p)`LONG_MAX`

if x = 0, otherwise the series precision as a `long`

integer.

This function simplifies x as much as it can. Specifically, a complex or
quadratic number whose imaginary part is the integer 0 (i.e. not `Mod(0,2)`

or `0.E-28`

) is converted to its real part, and a polynomial of degree 0
is converted to its constant term. Simplifications occur recursively.

This function is especially useful before using arithmetic functions, which expect integer arguments:

? x = 2 + y - y %1 = 2 ? isprime(x) *** at top-level: isprime(x) *** ^ — — — - *** isprime: not an integer argument in an arithmetic function ? type(x) %2 = "t_POL" ? type(simplify(x)) %3 = "t_INT"

Note that GP results are simplified as above before they are stored in the
history. (Unless you disable automatic simplification with `\y`

, that is.)
In particular

? type(%1) %4 = "t_INT"

The library syntax is `GEN `

.**simplify**(GEN x)

Outputs the total number of bytes occupied by the tree representing the PARI object x.

The library syntax is `long `

.
Also available is **gsizebyte**(GEN x)`long `

returning a
number of **gsizeword**(GEN x)*words*.

This function is DEPRECATED, essentially meaningless, and provided for backwards compatibility only. Don't use it!

outputs a quick upper bound for the number of decimal digits of (the
components of) x, off by at most 1. More precisely, for a positive
integer x, it computes (approximately) the ceiling of
`floor`

(1 + log_{2} x) log_{10}2,

To count the number of decimal digits of a positive integer x, use
`#digits(x)`

. To estimate (recursively) the size of x, use
`normlp(x)`

.

The library syntax is `long `

.**sizedigit**(GEN x)

Truncates x and sets e to the number of error bits. When x is in ℝ, this means that the part after the decimal point is chopped away, e is the binary exponent of the difference between the original and the truncated value (the "fractional part"). If the exponent of x is too large compared to its precision (i.e. e > 0), the result is undefined and an error occurs if e was not given. The function applies componentwise on vector / matrices; e is then the maximal number of error bits. If x is a rational function, the result is the "integer part" (Euclidean quotient of numerator by denominator) and e is not set.

Note a very special use of `truncate`

: when applied to a power series, it
transforms it into a polynomial or a rational function with denominator
a power of X, by chopping away the O(X^k). Similarly, when applied to
a p-adic number, it transforms it into an integer or a rational number
by chopping away the O(p^k).

The library syntax is `GEN `

.
The following functions are also available: **trunc0**(GEN x, GEN *e = NULL)`GEN `

and **gtrunc**(GEN x)`GEN `

.**gcvtoi**(GEN x, long *e)

Computes the highest exponent of p dividing x. If p is of type integer, x must be an integer, an intmod whose modulus is divisible by p, a fraction, a q-adic number with q = p, or a polynomial or power series in which case the valuation is the minimum of the valuation of the coefficients.

If p is of type polynomial, x must be of type polynomial or rational function, and also a power series if x is a monomial. Finally, the valuation of a vector, complex or quadratic number is the minimum of the component valuations.

If x = 0, the result is `+oo`

if x is an exact object. If x is a
p-adic numbers or power series, the result is the exponent of the zero.
Any other type combinations gives an error.

Finally, p can be omitted if x is a `t_PADIC`

(taken to be the
underlying prime), a `t_SER`

or a `t_POL`

(taken to be the main variable).

The library syntax is `GEN `

.
Also available is
**gpvaluation**(GEN x, GEN p = NULL)`long `

, which returns **gvaluation**(GEN x, GEN p)`LONG_MAX`

if x = 0
and the valuation as a `long`

integer.

Return a variable *name* whose priority is higher
than the priority of v (of all existing variables if v is omitted).
This is a counterpart to `varlower`

.

? Pol([x,x], t) *** at top-level: Pol([x,x],t) *** ^ — — — — *** Pol: incorrect priority in gtopoly: variable x <= t ? t = varhigher("t", x); ? Pol([x,x], t) %3 = x*t + x

This routine is useful since new GP variables directly created by the interpreter always have lower priority than existing GP variables. When some basic objects already exist in a variable that is incompatible with some function requirement, you can now create a new variable with a suitable priority instead of changing variables in existing objects:

? K = nfinit(x^2+1); ? rnfequation(K,y^2-2) *** at top-level: rnfequation(K,y^2-2) *** ^ — — — — — — -- *** rnfequation: incorrect priority in rnfequation: variable y >= x ? y = varhigher("y", x); ? rnfequation(K, y^2-2) %3 = y^4 - 2*y^2 + 9

**Caution 1.**
The *name* is an arbitrary character string, only used for display
purposes and need not be related to the GP variable holding the result, nor
to be a valid variable name. In particular the *name* can
not be used to retrieve the variable, it is not even present in the parser's
hash tables.

? x = varhigher("#"); ? x^2 %2 = #^2

**Caution 2.** There are a limited number of variables and if no
existing variable with the given display name has the requested
priority, the call to `varhigher`

uses up one such slot. Do not create
new variables in this way unless it's absolutely necessary,
reuse existing names instead and choose sensible priority requirements:
if you only need a variable with higher priority than x, state so
rather than creating a new variable with highest priority.

\\ quickly use up all variables ? n = 0; while(1,varhigher("tmp"); n++) *** at top-level: n=0;while(1,varhigher("tmp");n++) *** ^ — — — — — — - *** varhigher: no more variables available. *** Break loop: type 'break' to go back to GP prompt break> n 65510 \\ infinite loop: here we reuse the same 'tmp' ? n = 0; while(1,varhigher("tmp", x); n++)

The library syntax is `GEN `

where **varhigher**(const char *name, long v = -1)`v`

is a variable number.

Gives the main variable of the object x (the variable with the highest priority used in x), and p if x is a p-adic number. Return 0 if x has no variable attached to it.

? variable(x^2 + y) %1 = x ? variable(1 + O(5^2)) %2 = 5 ? variable([x,y,z,t]) %3 = x ? variable(1) %4 = 0

The construction

if (!variable(x),...)

can be used to test whether a variable is attached to x.

If x is omitted, returns the list of user variables known to the
interpreter, by order of decreasing priority. (Highest priority is initially
x, which come first until `varhigher`

is used.) If `varhigher`

or `varlower`

are used, it is quite possible to end up with different
variables (with different priorities) printed in the same way: they
will then appear multiple times in the output:

? varhigher("y"); ? varlower("y"); ? variable() %4 = [y, x, y]

Using `v = variable()`

then `v[1]`

, `v[2]`

,
etc. allows to recover and use existing variables.

The library syntax is `GEN `

.
However, in library mode, this function should not be used for x
non-**gpolvar**(GEN x = NULL)`NULL`

, since `gvar`

is more appropriate. Instead, for
x a p-adic (type `t_PADIC`

), p is gel(x,2); otherwise, use
`long `

which returns the variable number of x if
it exists, **gvar**(GEN x)`NO_VARIABLE`

otherwise, which satisfies the property
`varncmp`

(`NO_VARIABLE`

, v) > 0 for all valid variable number
v, i.e. it has lower priority than any variable.

Returns the list of all variables occurring in object x (all user variables known to the interpreter if x is omitted), sorted by decreasing priority.

? variables([x^2 + y*z + O(t), a+x]) %1 = [x, y, z, t, a]

The construction

if (!variables(x),...)

can be used to test whether a variable is attached to x.

If `varhigher`

or `varlower`

are used, it is quite possible to end up
with different variables (with different priorities) printed in the same
way: they will then appear multiple times in the output:

? y1 = varhigher("y"); ? y2 = varlower("y"); ? variables(y*y1*y2) %4 = [y, y, y]

The library syntax is `GEN `

.**variables_vec**(GEN x = NULL)

Also available is `GEN `

which returns
the (sorted) variable numbers instead of the attached monomials of degree 1.**variables_vecsmall**(GEN x)

Return a variable *name* whose priority is lower
than the priority of v (of all existing variables if v is omitted).
This is a counterpart to `varhigher`

.

New GP variables directly created by the interpreter always have lower priority than existing GP variables, but it is not easy to check whether an identifier is currently unused, so that the corresponding variable has the expected priority when it's created! Thus, depending on the session history, the same command may fail or succeed:

? t; z; \\ now t > z ? rnfequation(t^2+1,z^2-t) *** at top-level: rnfequation(t^2+1,z^ *** ^ — — — — — — -- *** rnfequation: incorrect priority in rnfequation: variable t >= t

Restart and retry:

? z; t; \\ now z > t ? rnfequation(t^2+1,z^2-t) %2 = z^4 + 1

It is quite annoying for package authors, when trying to define a base ring, to notice that the package may fail for some users depending on their session history. The safe way to do this is as follows:

? z; t; \\ In new session: now z > t ... ? t = varlower("t", 'z); ? rnfequation(t^2+1,z^2-2) %2 = z^4 - 2*z^2 + 9 ? variable() %3 = [x, y, z, t]

? t; z; \\ In new session: now t > z ... ? t = varlower("t", 'z); \\ create a new variable, still printed "t" ? rnfequation(t^2+1,z^2-2) %2 = z^4 - 2*z^2 + 9 ? variable() %3 = [x, y, t, z, t]

Now both constructions succeed. Note that in the
first case, `varlower`

is essentially a no-op, the existing variable t
has correct priority. While in the second case, two different variables are
displayed as `t`

, one with higher priority than z (created in the first
line) and another one with lower priority (created by `varlower`

).

**Caution 1.**
The *name* is an arbitrary character string, only used for display
purposes and need not be related to the GP variable holding the result, nor
to be a valid variable name. In particular the *name* can
not be used to retrieve the variable, it is not even present in the parser's
hash tables.

? x = varlower("#"); ? x^2 %2 = #^2

**Caution 2.** There are a limited number of variables and if no
existing variable with the given display name has the requested
priority, the call to `varlower`

uses up one such slot. Do not create
new variables in this way unless it's absolutely necessary,
reuse existing names instead and choose sensible priority requirements:
if you only need a variable with higher priority than x, state so
rather than creating a new variable with highest priority.

\\ quickly use up all variables ? n = 0; while(1,varlower("x"); n++) *** at top-level: n=0;while(1,varlower("x");n++) *** ^ — — — — — — - *** varlower: no more variables available. *** Break loop: type 'break' to go back to GP prompt break> n 65510 \\ infinite loop: here we reuse the same 'tmp' ? n = 0; while(1,varlower("tmp", x); n++)

The library syntax is `GEN `

where **varlower**(const char *name, long v = -1)`v`

is a variable number.