@@ -44,6 +44,11 @@ pub trait Field:
4444 /// A primitive element, i.e. a generator of the multiplicative group of the field.
4545 const GENERATOR : Self ;
4646
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+
4752 /// The order of the multiplicative group of the field.
4853 const MULTIPLICATIVE_ORDER : usize ;
4954
@@ -56,6 +61,47 @@ pub trait Field:
5661 /// Computes the multiplicative inverse of an element.
5762 fn multiplicative_inverse ( self ) -> Self ;
5863
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+
59105 /// Takes the element to the power of some integer.
60106 fn powi ( & self , mut n : i64 ) -> Self {
61107 let base = if n >= 0 {
@@ -71,7 +117,7 @@ pub trait Field:
71117 while mask > 0 {
72118 ret *= ret. clone ( ) ;
73119 if n & mask != 0 {
74- ret *= base. clone ( ) ;
120+ ret *= & base;
75121 }
76122 mask >>= 1 ;
77123 }
0 commit comments