Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/libs/ntl/ntl_ZZ.pyx
4102 views
1
#*****************************************************************************
2
# Copyright (C) 2005 William Stein <[email protected]>
3
#
4
# Distributed under the terms of the GNU General Public License (GPL)
5
#
6
# This code is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
# General Public License for more details.
10
#
11
# The full text of the GPL is available at:
12
#
13
# http://www.gnu.org/licenses/
14
#*****************************************************************************
15
16
include "../../ext/interrupt.pxi"
17
include "../../ext/stdsage.pxi"
18
include "../../ext/cdefs.pxi"
19
include "../../ext/random.pxi"
20
include 'misc.pxi'
21
include 'decl.pxi'
22
23
from sage.rings.integer import Integer
24
from sage.rings.integer_ring import IntegerRing
25
from sage.rings.integer cimport Integer
26
from sage.rings.integer_ring cimport IntegerRing_class
27
28
ZZ_sage = IntegerRing()
29
30
cdef make_ZZ(ZZ_c* x):
31
cdef ntl_ZZ y
32
y = ntl_ZZ()
33
y.x = x[0]
34
ZZ_delete(x)
35
sig_off()
36
return y
37
38
39
##############################################################################
40
# ZZ: Arbitrary precision integers
41
##############################################################################
42
43
cdef class ntl_ZZ:
44
r"""
45
The \class{ZZ} class is used to represent signed, arbitrary length integers.
46
47
Routines are provided for all of the basic arithmetic operations, as
48
well as for some more advanced operations such as primality testing.
49
Space is automatically managed by the constructors and destructors.
50
51
This module also provides routines for generating small primes, and
52
fast routines for performing modular arithmetic on single-precision
53
numbers.
54
"""
55
# See ntl.pxd for definition of data members
56
def __init__(self, v=None):
57
r"""
58
Initializes and NTL integer.
59
60
EXAMPLES::
61
62
sage: ntl.ZZ(12r)
63
12
64
sage: ntl.ZZ(Integer(95413094))
65
95413094
66
sage: ntl.ZZ(long(223895239852389582983))
67
223895239852389582983
68
sage: ntl.ZZ('-1')
69
-1
70
sage: ntl.ZZ('1L')
71
1
72
sage: ntl.ZZ('-1r')
73
-1
74
75
TESTS::
76
77
sage: ntl.ZZ(int(2**40))
78
1099511627776
79
80
AUTHOR: Joel B. Mohler (2007-06-14)
81
"""
82
if PY_TYPE_CHECK(v, ntl_ZZ):
83
self.x = (<ntl_ZZ>v).x
84
elif PyInt_Check(v):
85
ZZ_conv_from_int(self.x, PyInt_AS_LONG(v))
86
elif PyLong_Check(v):
87
ZZ_set_pylong(self.x, v)
88
elif PY_TYPE_CHECK(v, Integer):
89
self.set_from_sage_int(v)
90
elif v is not None:
91
v = str(v)
92
if len(v) == 0:
93
v = '0'
94
if not ((v[0].isdigit() or v[0] == '-') and \
95
(v[1:-1].isdigit() or (len(v) <= 2)) and \
96
(v[-1].isdigit() or (v[-1].lower() in ['l','r']))):
97
raise ValueError, "invalid integer: %s"%v
98
sig_on()
99
ZZ_from_str(&self.x, v)
100
sig_off()
101
102
def __cinit__(self):
103
ZZ_construct(&self.x)
104
105
def __dealloc__(self):
106
ZZ_destruct(&self.x)
107
108
def __repr__(self):
109
"""
110
Return the string representation of self.
111
112
EXAMPLES:
113
sage: ntl.ZZ(5).__repr__()
114
'5'
115
"""
116
return ZZ_to_PyString(&self.x)
117
118
def __reduce__(self):
119
"""
120
sage: from sage.libs.ntl.ntl_ZZ import ntl_ZZ
121
sage: a = ntl_ZZ(-7)
122
sage: loads(dumps(a))
123
-7
124
"""
125
return unpickle_class_value, (ntl_ZZ, self._integer_())
126
127
def __cmp__(self, other):
128
"""
129
Compare self to other.
130
131
EXAMPLES:
132
sage: f = ntl.ZZ(1)
133
sage: g = ntl.ZZ(2)
134
sage: h = ntl.ZZ(2)
135
sage: w = ntl.ZZ(7)
136
sage: h == g
137
True
138
sage: f == g
139
False
140
sage: h > w ## indirect doctest
141
False
142
sage: h < w
143
True
144
"""
145
if (type(self) != type(other)):
146
return cmp(type(self), type(other))
147
diff = self.__sub__(other)
148
if ZZ_IsZero( (<ntl_ZZ>diff).x ):
149
return 0
150
elif ZZ_sign( (<ntl_ZZ>diff).x ) == 1:
151
return 1
152
else:
153
return -1
154
155
def __hash__(self):
156
"""
157
Return the hash of this integer.
158
159
Agrees with the hash of the corresponding sage integer.
160
"""
161
cdef Integer v = PY_NEW(Integer)
162
ZZ_to_mpz(&v.value, &self.x)
163
return v.hash_c()
164
165
def __mul__(self, other):
166
"""
167
sage: n=ntl.ZZ(2983)*ntl.ZZ(2)
168
sage: n
169
5966
170
"""
171
cdef ntl_ZZ r = PY_NEW(ntl_ZZ)
172
if not PY_TYPE_CHECK(self, ntl_ZZ):
173
self = ntl_ZZ(self)
174
if not PY_TYPE_CHECK(other, ntl_ZZ):
175
other = ntl_ZZ(other)
176
sig_on()
177
ZZ_mul(r.x, (<ntl_ZZ>self).x, (<ntl_ZZ>other).x)
178
sig_off()
179
return r
180
181
def __sub__(self, other):
182
"""
183
sage: n=ntl.ZZ(2983)-ntl.ZZ(2)
184
sage: n
185
2981
186
sage: ntl.ZZ(2983)-2
187
2981
188
"""
189
cdef ntl_ZZ r = PY_NEW(ntl_ZZ)
190
if not PY_TYPE_CHECK(self, ntl_ZZ):
191
self = ntl_ZZ(self)
192
if not PY_TYPE_CHECK(other, ntl_ZZ):
193
other = ntl_ZZ(other)
194
ZZ_sub(r.x, (<ntl_ZZ>self).x, (<ntl_ZZ>other).x)
195
return r
196
197
def __add__(self, other):
198
"""
199
sage: n=ntl.ZZ(2983)+ntl.ZZ(2)
200
sage: n
201
2985
202
sage: ntl.ZZ(23)+2
203
25
204
"""
205
cdef ntl_ZZ r = PY_NEW(ntl_ZZ)
206
if not PY_TYPE_CHECK(self, ntl_ZZ):
207
self = ntl_ZZ(self)
208
if not PY_TYPE_CHECK(other, ntl_ZZ):
209
other = ntl_ZZ(other)
210
ZZ_add(r.x, (<ntl_ZZ>self).x, (<ntl_ZZ>other).x)
211
return r
212
213
def __neg__(ntl_ZZ self):
214
"""
215
sage: x = ntl.ZZ(38)
216
sage: -x
217
-38
218
sage: x.__neg__()
219
-38
220
"""
221
cdef ntl_ZZ r = PY_NEW(ntl_ZZ)
222
ZZ_negate(r.x, self.x)
223
return r
224
225
def __pow__(ntl_ZZ self, long e, ignored):
226
"""
227
sage: ntl.ZZ(23)^50
228
122008981252869411022491112993141891091036959856659100591281395343249
229
"""
230
cdef ntl_ZZ r = ntl_ZZ()
231
sig_on()
232
ZZ_power(r.x, self.x, e)
233
sig_off()
234
return r
235
236
def __int__(self):
237
"""
238
Return self as an int.
239
240
EXAMPLES:
241
sage: ntl.ZZ(22).__int__()
242
22
243
sage: type(ntl.ZZ(22).__int__())
244
<type 'int'>
245
246
sage: ntl.ZZ(10^30).__int__()
247
1000000000000000000000000000000L
248
sage: type(ntl.ZZ(10^30).__int__())
249
<type 'long'>
250
"""
251
return int(self._integer_())
252
253
cdef int get_as_int(ntl_ZZ self):
254
r"""
255
Returns value as C int.
256
Return value is only valid if the result fits into an int.
257
258
AUTHOR: David Harvey (2006-08-05)
259
"""
260
cdef int ans
261
ZZ_conv_to_int(ans, self.x)
262
return ans
263
264
def get_as_int_doctest(self):
265
r"""
266
This method exists solely for automated testing of get_as_int().
267
268
sage: x = ntl.ZZ(42)
269
sage: i = x.get_as_int_doctest()
270
sage: print i
271
42
272
sage: print type(i)
273
<type 'int'>
274
"""
275
return self.get_as_int()
276
277
def _integer_(self, ZZ=None):
278
r"""
279
Gets the value as a sage int.
280
281
sage: n=ntl.ZZ(2983)
282
sage: type(n._integer_())
283
<type 'sage.rings.integer.Integer'>
284
285
AUTHOR: Joel B. Mohler
286
"""
287
cdef Integer ans = PY_NEW(Integer)
288
ZZ_to_mpz(&ans.value, &self.x)
289
return ans
290
#return (<IntegerRing_class>ZZ_sage)._coerce_ZZ(&self.x)
291
292
cdef void set_from_int(ntl_ZZ self, int value):
293
r"""
294
Sets the value from a C int.
295
296
AUTHOR: David Harvey (2006-08-05)
297
"""
298
ZZ_conv_from_int(self.x, value)
299
300
def set_from_sage_int(self, Integer value):
301
r"""
302
Sets the value from a sage int.
303
304
EXAMPLES:
305
sage: n=ntl.ZZ(2983)
306
sage: n
307
2983
308
sage: n.set_from_sage_int(1234)
309
sage: n
310
1234
311
312
AUTHOR: Joel B. Mohler
313
"""
314
sig_on()
315
value._to_ZZ(&self.x)
316
sig_off()
317
318
def set_from_int_doctest(self, value):
319
r"""
320
This method exists solely for automated testing of set_from_int().
321
322
sage: x = ntl.ZZ()
323
sage: x.set_from_int_doctest(42)
324
sage: x
325
42
326
"""
327
self.set_from_int(int(value))
328
329
def valuation(self, ntl_ZZ prime):
330
"""
331
Uses code in ntl_wrap.cpp to compute the number of times prime divides self.
332
333
EXAMPLES:
334
sage: a = ntl.ZZ(5^7*3^4)
335
sage: p = ntl.ZZ(5)
336
sage: a.valuation(p)
337
7
338
sage: a.valuation(-p)
339
7
340
sage: b = ntl.ZZ(0)
341
sage: b.valuation(p)
342
+Infinity
343
"""
344
cdef ntl_ZZ ans = PY_NEW(ntl_ZZ)
345
cdef ntl_ZZ unit = PY_NEW(ntl_ZZ)
346
cdef long valuation
347
if ZZ_IsZero(self.x):
348
from sage.rings.infinity import infinity
349
return infinity
350
sig_on()
351
valuation = ZZ_remove(unit.x, self.x, prime.x)
352
sig_off()
353
ZZ_conv_from_long(ans.x, valuation)
354
return ans
355
356
def val_unit(self, ntl_ZZ prime):
357
"""
358
Uses code in ntl_wrap.cpp to compute p-adic valuation and unit of self.
359
360
EXAMPLES:
361
sage: a = ntl.ZZ(5^7*3^4)
362
sage: p = ntl.ZZ(-5)
363
sage: a.val_unit(p)
364
(7, -81)
365
sage: a.val_unit(ntl.ZZ(-3))
366
(4, 78125)
367
sage: a.val_unit(ntl.ZZ(2))
368
(0, 6328125)
369
"""
370
cdef ntl_ZZ val = PY_NEW(ntl_ZZ)
371
cdef ntl_ZZ unit = PY_NEW(ntl_ZZ)
372
cdef long valuation
373
sig_on()
374
valuation = ZZ_remove(unit.x, self.x, prime.x)
375
sig_off()
376
ZZ_conv_from_long(val.x, valuation)
377
return val, unit
378
379
# todo: add wrapper for int_to_ZZ in wrap.cc?
380
381
def unpickle_class_value(cls, x):
382
"""
383
Here for unpickling.
384
385
EXAMPLES:
386
sage: sage.libs.ntl.ntl_ZZ.unpickle_class_value(ntl.ZZ, 3)
387
3
388
sage: type(sage.libs.ntl.ntl_ZZ.unpickle_class_value(ntl.ZZ, 3))
389
<type 'sage.libs.ntl.ntl_ZZ.ntl_ZZ'>
390
"""
391
return cls(x)
392
393
def unpickle_class_args(cls, x):
394
"""
395
Here for unpickling.
396
397
EXAMPLES:
398
sage: sage.libs.ntl.ntl_ZZ.unpickle_class_args(ntl.ZZ, [3])
399
3
400
sage: type(sage.libs.ntl.ntl_ZZ.unpickle_class_args(ntl.ZZ, [3]))
401
<type 'sage.libs.ntl.ntl_ZZ.ntl_ZZ'>
402
"""
403
return cls(*x)
404
405
# Random-number generation
406
def ntl_setSeed(x=None):
407
r"""
408
Seed the NTL random number generator.
409
410
This is automatically called when you set the main \sage random
411
number seed, then call any NTL routine requiring random numbers;
412
so you should never need to call this directly.
413
414
If for some reason you do need to call this directly, then
415
you need to get a random number from NTL (so that \sage will
416
seed NTL), then call this function and \sage will not notice.
417
418
EXAMPLE:
419
This is automatically seeded from the main \sage random number seed.
420
sage: ntl.ZZ_random(1000)
421
341
422
423
Now you can call this function, and it will not be overridden until
424
the next time the main \sage random number seed is changed.
425
sage: ntl.ntl_setSeed(10)
426
sage: ntl.ZZ_random(1000)
427
776
428
"""
429
cdef ntl_ZZ seed = ntl_ZZ(1)
430
if x is None:
431
from random import randint
432
seed = ntl_ZZ(str(randint(0,int(2)**64)))
433
else:
434
seed = ntl_ZZ(str(x))
435
sig_on()
436
ZZ_SetSeed(seed.x)
437
sig_off()
438
439
ntl_setSeed()
440
441
442
def randomBnd(q):
443
r"""
444
Returns random number in the range [0,n) .
445
According to the NTL documentation, these numbers are
446
"cryptographically strong"; of course, that depends in part on
447
how they are seeded.
448
449
EXAMPLES:
450
sage: [ntl.ZZ_random(99999) for i in range(5)]
451
[82123, 14857, 53872, 13159, 83337]
452
453
AUTHOR:
454
-- Didier Deshommes <[email protected]>
455
"""
456
current_randstate().set_seed_ntl(False)
457
458
cdef ntl_ZZ w
459
460
if not PY_TYPE_CHECK(q, ntl_ZZ):
461
q = ntl_ZZ(str(q))
462
w = q
463
cdef ntl_ZZ ans
464
ans = PY_NEW(ntl_ZZ)
465
sig_on()
466
ZZ_RandomBnd(ans.x, w.x)
467
sig_off()
468
return ans
469
470
def randomBits(long n):
471
r"""
472
Return a pseudo-random number between 0 and $2^n-1$
473
474
EXAMPLES:
475
sage: [ntl.ZZ_random_bits(20) for i in range(3)]
476
[564629, 843071, 972038]
477
478
AUTHOR:
479
-- Didier Deshommes <[email protected]>
480
"""
481
current_randstate().set_seed_ntl(False)
482
483
cdef ntl_ZZ ans
484
ans = PY_NEW(ntl_ZZ)
485
sig_on()
486
ZZ_RandomBits(ans.x, n)
487
sig_off()
488
return ans
489
490