@@ -44,6 +44,11 @@ pub trait Field:
44
44
/// A primitive element, i.e. a generator of the multiplicative group of the field.
45
45
const GENERATOR : Self ;
46
46
47
+ /// The smallest integer n such that 1 + ... + 1, n times, equals 0.
48
+ ///
49
+ /// If this is 0, this indicates that no such integer exists.
50
+ const CHARACTERISTIC : usize ;
51
+
47
52
/// The order of the multiplicative group of the field.
48
53
const MULTIPLICATIVE_ORDER : usize ;
49
54
@@ -56,6 +61,47 @@ pub trait Field:
56
61
/// Computes the multiplicative inverse of an element.
57
62
fn multiplicative_inverse ( self ) -> Self ;
58
63
64
+ /// Takes the element times some integer.
65
+ fn muli ( & self , mut n : i64 ) -> Self {
66
+ let base = if n >= 0 {
67
+ self . clone ( )
68
+ } else {
69
+ n *= -1 ;
70
+ self . clone ( ) . multiplicative_inverse ( )
71
+ } ;
72
+
73
+ let mut ret = Self :: ZERO ;
74
+ // Special case some particular characteristics
75
+ match Self :: CHARACTERISTIC {
76
+ 1 => unreachable ! ( "no field has characteristic 1" ) ,
77
+ 2 => {
78
+ // Special-case 2 because it's easy and also the only characteristic used
79
+ // within the library. The compiler should prune away the other code.
80
+ if n % 2 == 0 {
81
+ Self :: ZERO
82
+ } else {
83
+ self . clone ( )
84
+ }
85
+ }
86
+ x => {
87
+ // This is identical to powi below, but with * replaced by +.
88
+ if x > 0 {
89
+ n %= x as i64 ;
90
+ }
91
+
92
+ let mut mask = x. next_power_of_two ( ) as i64 ;
93
+ while mask > 0 {
94
+ ret += ret. clone ( ) ;
95
+ if n & mask != 0 {
96
+ ret += & base;
97
+ }
98
+ mask >>= 1 ;
99
+ }
100
+ ret
101
+ }
102
+ }
103
+ }
104
+
59
105
/// Takes the element to the power of some integer.
60
106
fn powi ( & self , mut n : i64 ) -> Self {
61
107
let base = if n >= 0 {
@@ -71,7 +117,7 @@ pub trait Field:
71
117
while mask > 0 {
72
118
ret *= ret. clone ( ) ;
73
119
if n & mask != 0 {
74
- ret *= base. clone ( ) ;
120
+ ret *= & base;
75
121
}
76
122
mask >>= 1 ;
77
123
}
0 commit comments