1 /* 2 Copyright (C) 2009 William Hart 3 4 This file is part of FLINT. 5 6 FLINT is free software: you can redistribute it and/or modify it under 7 the terms of the GNU Lesser General Public License (LGPL) as published 8 by the Free Software Foundation; either version 2.1 of the License, or 9 (at your option) any later version. See <http://www.gnu.org/licenses/>. 10 */ 11 12 #include <stdlib.h> 13 #include <gmp.h> 14 #include "flint.h" 15 #include "fmpz.h" 16 _fmpz_new_mpz(void)17__mpz_struct * _fmpz_new_mpz(void) 18 { 19 __mpz_struct * mpz_ptr = (__mpz_struct *) flint_malloc(sizeof(__mpz_struct)); 20 mpz_init2(mpz_ptr, 2*FLINT_BITS); 21 return mpz_ptr; 22 } 23 _fmpz_clear_mpz(fmpz f)24void _fmpz_clear_mpz(fmpz f) 25 { 26 mpz_clear(COEFF_TO_PTR(f)); 27 flint_free(COEFF_TO_PTR(f)); 28 } 29 _fmpz_cleanup_mpz_content(void)30void _fmpz_cleanup_mpz_content(void) 31 { 32 } 33 _fmpz_cleanup(void)34void _fmpz_cleanup(void) 35 { 36 } 37 _fmpz_promote(fmpz_t f)38__mpz_struct * _fmpz_promote(fmpz_t f) 39 { 40 if (!COEFF_IS_MPZ(*f)) /* f is small so promote it first */ 41 { 42 __mpz_struct * mpz_ptr = _fmpz_new_mpz(); 43 *f = PTR_TO_COEFF(mpz_ptr); 44 return mpz_ptr; 45 } 46 else /* f is large already, just return the pointer */ 47 return COEFF_TO_PTR(*f); 48 } 49 _fmpz_promote_val(fmpz_t f)50__mpz_struct * _fmpz_promote_val(fmpz_t f) 51 { 52 fmpz c = *f; 53 if (!COEFF_IS_MPZ(c)) /* f is small so promote it */ 54 { 55 __mpz_struct * mpz_ptr = _fmpz_new_mpz(); 56 *f = PTR_TO_COEFF(mpz_ptr); 57 flint_mpz_set_si(mpz_ptr, c); 58 return mpz_ptr; 59 } 60 else /* f is large already, just return the pointer */ 61 return COEFF_TO_PTR(*f); 62 } 63 _fmpz_demote_val(fmpz_t f)64void _fmpz_demote_val(fmpz_t f) 65 { 66 __mpz_struct * mpz_ptr = COEFF_TO_PTR(*f); 67 int size = mpz_ptr->_mp_size; 68 69 if (!(((unsigned int) size + 1U) & ~2U)) /* size +-1 */ 70 { 71 ulong uval = mpz_ptr->_mp_d[0]; 72 73 if (uval <= (ulong) COEFF_MAX) 74 { 75 _fmpz_clear_mpz(*f); 76 *f = size * (fmpz) uval; 77 } 78 } 79 else if (size == 0) /* value is 0 */ 80 { 81 _fmpz_clear_mpz(*f); 82 *f = 0; 83 } 84 85 /* don't do anything if value has to be multi precision */ 86 } 87 _fmpz_init_readonly_mpz(fmpz_t f,const mpz_t z)88void _fmpz_init_readonly_mpz(fmpz_t f, const mpz_t z) 89 { 90 __mpz_struct * mpz_ptr = (__mpz_struct *) flint_malloc(sizeof(__mpz_struct)); 91 *f = PTR_TO_COEFF(mpz_ptr); 92 *mpz_ptr = *z; 93 } 94 _fmpz_clear_readonly_mpz(mpz_t z)95void _fmpz_clear_readonly_mpz(mpz_t z) 96 { 97 if (((z->_mp_size == 1 || z->_mp_size == -1) && (z->_mp_d[0] <= COEFF_MAX)) 98 || (z->_mp_size == 0)) 99 { 100 mpz_clear(z); 101 } 102 } 103