Ignore:
Timestamp:
02/28/07 23:18:24 (6 years ago)
Author:
Carl Witty <cwitty@…>
Branch:
default
Message:

Convert floating-point numbers from MPFR to Pari accurately.

Also, this version avoids binary-to-decimal and decimal-to-binary
conversions, which improves the asymptotic run-time from superlinear
(quadratic?) to linear.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sage/rings/real_mpfr.pyx

    r3277 r3278  
    4040import sys 
    4141 
     42include '../ext/cdefs.pxi' 
    4243include '../ext/interrupt.pxi' 
    4344include "../ext/stdsage.pxi" 
     45include '../libs/pari/decl.pxi' 
    4446 
    4547cimport sage.rings.ring 
     
    5052import  sage.structure.element 
    5153 
     54import sage.misc.misc as misc 
     55 
    5256import sage.structure.coerce 
    5357import operator 
     58 
     59from sage.libs.pari.gen import PariInstance 
     60from sage.libs.pari.gen cimport PariInstance 
    5461 
    5562from integer import Integer 
     
    11031110 
    11041111    def _pari_(self): 
    1105         return sage.libs.pari.all.pari.new_with_bits_prec(str(self), (<RealField>self._parent).__prec) 
    1106          
     1112        """ 
     1113        Returns self as a Pari floating-point number. 
     1114 
     1115        EXAMPLES: 
     1116            sage: RR(2.0)._pari_() 
     1117            2.000000000000000000 
     1118            sage: RealField(250).pi()._pari_() 
     1119            3.141592653589793238462643383 
     1120            sage: RR(0.0)._pari_() 
     1121            0.E-19 
     1122            sage: RR(-1.234567)._pari_() 
     1123            -1.2345669999999999700 
     1124        """ 
     1125        # return sage.libs.pari.all.pari.new_with_bits_prec(str(self), (<RealField>self._parent).__prec) 
     1126 
     1127        # This uses interfaces of MPFR and Pari which are documented 
     1128        # (and not marked subject-to-change).  It could be faster 
     1129        # by using internal interfaces of MPFR, which are documented 
     1130        # as subject-to-change. 
     1131 
     1132        if mpfr_nan_p(self.value) or mpfr_inf_p(self.value): 
     1133            raise ValueError, 'Cannot convert NaN or infinity to Pari float' 
     1134 
     1135        cdef int wordsize 
     1136 
     1137        if sage.misc.misc.is_64_bit: 
     1138            wordsize = 64 
     1139        else: 
     1140            wordsize = 32 
     1141 
     1142        cdef int prec 
     1143        prec = (<RealField>self._parent).__prec 
     1144 
     1145        # We round up the precision to the nearest multiple of wordsize. 
     1146        cdef int rounded_prec 
     1147        rounded_prec = (self.prec() + wordsize - 1) & ~(wordsize - 1) 
     1148 
     1149        # Yes, assigning to self works fine, even in Pyrex. 
     1150        if rounded_prec > prec: 
     1151            self = RealField(rounded_prec)(self) 
     1152 
     1153        # Now we can extract the mantissa, and it will be normalized 
     1154        # (the most significant bit of the most significant word will be 1). 
     1155        cdef mpz_t mantissa 
     1156        cdef mp_exp_t exponent 
     1157        mpz_init(mantissa) 
     1158 
     1159        exponent = mpfr_get_z_exp(mantissa, self.value) 
     1160 
     1161        cdef GEN pari_float 
     1162        pari_float = cgetr(2 + rounded_prec / wordsize) 
     1163 
     1164        mpz_export(&pari_float[2], NULL, 1, wordsize/8, 0, 0, mantissa) 
     1165 
     1166        if mpfr_zero_p(self.value): 
     1167            setexpo(pari_float, -rounded_prec) 
     1168        else: 
     1169            setexpo(pari_float, exponent + rounded_prec - 1) 
     1170        setsigne(pari_float, mpfr_sgn(self.value)) 
     1171 
     1172        cdef PariInstance P 
     1173        P = sage.libs.pari.all.pari 
     1174         
     1175        gen = P.new_gen(pari_float) 
     1176 
     1177        mpz_clear(mantissa) 
     1178 
     1179        return gen 
    11071180 
    11081181    ########################################### 
Note: See TracChangeset for help on using the changeset viewer.