@@ -360,53 +360,58 @@ cdef class fmpz(flint_scalar):
360
360
return u
361
361
362
362
def __pow__ (s , t , m ):
363
+ cdef fmpz_struct sval[1 ]
363
364
cdef fmpz_struct tval[1 ]
364
365
cdef fmpz_struct mval[1 ]
366
+ cdef int stype = FMPZ_UNKNOWN
365
367
cdef int ttype = FMPZ_UNKNOWN
366
368
cdef int mtype = FMPZ_UNKNOWN
367
369
cdef int success
368
370
u = NotImplemented
369
- ttype = fmpz_set_any_ref(tval, t)
370
- if ttype == FMPZ_UNKNOWN:
371
- return NotImplemented
372
371
373
- if m is None :
374
- # fmpz_pow_fmpz throws if x is negative
375
- if fmpz_sgn(tval) == - 1 :
376
- if ttype == FMPZ_TMP: fmpz_clear(tval)
377
- raise ValueError (" negative exponent" )
372
+ try :
373
+ stype = fmpz_set_any_ref(sval, s)
374
+ if stype == FMPZ_UNKNOWN:
375
+ return NotImplemented
376
+ ttype = fmpz_set_any_ref(tval, t)
377
+ if ttype == FMPZ_UNKNOWN:
378
+ return NotImplemented
379
+ if m is None :
380
+ # fmpz_pow_fmpz throws if x is negative
381
+ if fmpz_sgn(tval) == - 1 :
382
+ raise ValueError (" negative exponent" )
378
383
379
- u = fmpz.__new__ (fmpz)
380
- success = fmpz_pow_fmpz((< fmpz> u).val, (< fmpz> s).val, tval)
384
+ u = fmpz.__new__ (fmpz)
385
+ success = fmpz_pow_fmpz((< fmpz> u).val, (< fmpz> s).val, tval)
381
386
382
- if not success:
383
- if ttype == FMPZ_TMP: fmpz_clear(tval)
384
- raise OverflowError (" fmpz_pow_fmpz: exponent too large" )
385
- else :
386
- # Modular exponentiation
387
- mtype = fmpz_set_any_ref(mval, m)
388
- if mtype != FMPZ_UNKNOWN:
387
+ if not success:
388
+ raise OverflowError (" fmpz_pow_fmpz: exponent too large" )
389
+
390
+ return u
391
+ else :
392
+ # Modular exponentiation
393
+ mtype = fmpz_set_any_ref(mval, m)
394
+ if mtype == FMPZ_UNKNOWN:
395
+ return NotImplemented
389
396
390
397
if fmpz_is_zero(mval):
391
- if ttype == FMPZ_TMP: fmpz_clear(tval)
392
- if mtype == FMPZ_TMP: fmpz_clear(mval)
393
398
raise ValueError (" pow(): modulus cannot be zero" )
394
399
395
400
# The Flint docs say that fmpz_powm will throw if m is zero
396
401
# but it also throws if m is negative. Python generally allows
397
402
# e.g. pow(2, 2, -3) == (2^2) % (-3) == -2. We could implement
398
403
# that here as well but it is not clear how useful it is.
399
404
if fmpz_sgn(mval) == - 1 :
400
- if ttype == FMPZ_TMP: fmpz_clear(tval)
401
- if mtype == FMPZ_TMP: fmpz_clear(mval)
402
- raise ValueError (" pow(): negative modulua not supported" )
405
+ raise ValueError (" pow(): negative modulus not supported" )
403
406
404
407
u = fmpz.__new__ (fmpz)
405
- fmpz_powm((< fmpz> u).val, ( < fmpz > s).val , tval, mval)
408
+ fmpz_powm((< fmpz> u).val, sval , tval, mval)
406
409
407
- if ttype == FMPZ_TMP: fmpz_clear(tval)
408
- if mtype == FMPZ_TMP: fmpz_clear(mval)
409
- return u
410
+ return u
411
+ finally :
412
+ if stype == FMPZ_TMP: fmpz_clear(sval)
413
+ if ttype == FMPZ_TMP: fmpz_clear(tval)
414
+ if mtype == FMPZ_TMP: fmpz_clear(mval)
410
415
411
416
def __rpow__ (s , t , m ):
412
417
t = any_as_fmpz(t)
0 commit comments