diff --git a/doc/ref/fieldfin.xml b/doc/ref/fieldfin.xml index 6f7bd019ffa..f8ce185dc13 100644 --- a/doc/ref/fieldfin.xml +++ b/doc/ref/fieldfin.xml @@ -179,8 +179,8 @@ Finally note that elements of large prime fields are stored and displayed as residue class objects. So
must be a prime"); + Error("Z:
must be a prime (not the integer ", p, ")");
fi;
q := p^d;
if q <= MAXSIZE_GF_INTERNAL or d =1 then
diff --git a/lib/ffe.gd b/lib/ffe.gd
index 955f0cb3517..7fb75d7a727 100644
--- a/lib/ffe.gd
+++ b/lib/ffe.gd
@@ -18,6 +18,7 @@
## must be a prime");
+ Error("Z: must be a prime (not the integer ", p, ")");
fi;
q := p^d;
if q <= MAXSIZE_GF_INTERNAL or d =1 then
diff --git a/src/finfield.c b/src/finfield.c
index 37bf5fbfece..b20b9e05d7c 100644
--- a/src/finfield.c
+++ b/src/finfield.c
@@ -1448,10 +1448,10 @@ static Obj FuncZ(Obj self, Obj q)
FF ff; /* the finite field */
/* check the argument */
- if ( (IS_INTOBJ(q) && (INT_INTOBJ(q) > 65536)) ||
- (TNUM_OBJ(q) == T_INTPOS))
- return CALL_1ARGS(ZOp, q);
-
+ if ((IS_INTOBJ(q) && (INT_INTOBJ(q) > MAXSIZE_GF_INTERNAL)) ||
+ (TNUM_OBJ(q) == T_INTPOS))
+ return CALL_1ARGS(ZOp, q);
+
if ( !IS_INTOBJ(q) || INT_INTOBJ(q)<=1 ) {
RequireArgument("Z", q, "must be a positive prime power");
}
@@ -1474,20 +1474,21 @@ static Obj FuncZ2(Obj self, Obj p, Obj d)
if (ARE_INTOBJS(p, d)) {
ip = INT_INTOBJ(p);
id = INT_INTOBJ(d);
- if (ip > 1 && id > 0 && id <= 16 && ip < 65536) {
+ if (ip > 1 && id > 0 && id <= DEGREE_LARGEST_INTERNAL_FF &&
+ ip <= MAXSIZE_GF_INTERNAL) {
id1 = id;
q = ip;
- while (--id1 > 0 && q <= 65536)
+ while (--id1 > 0 && q <= MAXSIZE_GF_INTERNAL)
q *= ip;
- if (q <= 65536) {
+ if (q <= MAXSIZE_GF_INTERNAL) {
/* get the finite field */
- ff = FiniteField(ip, id);
+ ff = FiniteFieldBySize(q);
if (ff == 0 || CHAR_FF(ff) != ip)
RequireArgument("Z", p, "must be a prime");
/* make the root */
- return NEW_FFE(ff, (ip == 2 && id == 1 ? 1 : 2));
+ return NEW_FFE(ff, (q == 2) ? 1 : 2);
}
}
}
diff --git a/src/finfield.h b/src/finfield.h
index c509e4de357..d38d71ce9d6 100644
--- a/src/finfield.h
+++ b/src/finfield.h
@@ -12,8 +12,11 @@
**
** Finite fields are an important domain in computational group theory
** because the classical matrix groups are defined over those finite fields.
-** In GAP we support small finite fields with up to 65536 elements,
-** larger fields can be realized as polynomial domains over smaller fields.
+** The GAP kernel supports elements of finite fields up to some fixed size
+** limit, typically 2^16 on 32 bit systems and 2^24 on 64 bit systems.
+** To change the limits, edit etc/ffgen.c. To access the current limits use
+** MAXSIZE_GF_INTERNAL. Support for larger fields is implemented by the
+** library
**
** Elements in small finite fields are represented as immediate objects.
**
@@ -24,10 +27,11 @@
** The least significant 3 bits of such an immediate object are always 010,
** flagging the object as an object of a small finite field.
**
-** The next 13 bits represent the small finite field where the element lies.
-** They are simply an index into a global table of small finite fields.
+** The next group of FIELD_BITS_FFE bits represent the small finite field
+** where the element lies. They are simply an index into a global table of
+** small finite fields, which is constructed at build time.
**
-** The most significant 16 bits represent the value of the element.
+** The most significant VAL_BITS_FFE bits represent the value of the element.
**
** If the value is 0, then the element is the zero from the finite field.
** Otherwise the integer is the logarithm of this element with respect to a
@@ -64,10 +68,9 @@
**
** Small finite fields are represented by an index into a global table.
**
-** Since there are only 6542 (prime) + 93 (nonprime) small finite fields,
-** the index fits into a 'UInt2' (actually into 13 bits).
+** Depending on the configuration it may be UInt2 or UInt4. The definition
+** is in `ffdata.h` and is calculated by etc/ffgen.c
*/
-typedef UInt2 FF;
/****************************************************************************
@@ -131,17 +134,9 @@ extern Obj SuccFF;
** Values of elements of small finite fields are represented by the
** logarithm of the element with respect to the root plus one.
**
-** Since small finite fields contain at most 65536 elements, the value fits
-** into a 'UInt2'.
-**
-** It may be possible to change this to 'UInt4' to allow small finite fields
-** with more than than 65536 elements. The macros and have been coded in
-** such a way that they work without problems. The exception is 'POW_FFV'
-** which will only work if the product of integers of type 'FFV' does not
-** cause an overflow. And of course the successor table stored for a finite
-** field will become quite large for fields with more than 65536 elements.
+** Depending on the configuration, this type may be a UInt2 or UInt4.
+** This type is actually defined in gen/ffdata.h by etc/ffgen.c
*/
-typedef UInt2 FFV;
GAP_STATIC_ASSERT(sizeof(UInt) >= 2 * sizeof(FFV),
"Overflow possibility in POW_FFV");
@@ -276,11 +271,12 @@ EXPORT_INLINE FFV QUO_FFV(FFV a, FFV b, const FFV * f)
** the finite field pointed to by the pointer must be a prime (not the integer 9)
gap> Z(9,2);
Error, Z: must be a prime (not the integer 9)
gap> Z(2^16,1);
-Error, Z: must be a prime
+Error, Z: must be a prime (not the integer 65536)
gap> Z(2^16,2);
-Error, Z: must be a prime
+Error, Z: must be a prime (not the integer 65536)
gap> Z(2^17,1);
-Error, Z: must be a prime
+Error, Z: must be a prime (not the integer 131072)
gap> Z(2^17,2);
-Error, Z: must be a prime
+Error, Z: must be a prime (not the integer 131072)
# Invoking Z(p,d) with p not a prime used to crash gap, which we fixed.
# However, invocations like `Z(4,5)` still would erroneously trigger the