@@ -17,44 +17,47 @@ typedef struct {
1717
1818
1919/*
20- * It would be slightly easier/faster to store the internals, but use the
21- * proper public API here:
20+ * It would be more compat to just store the kind, exponent and signfificand,
21+ * however. For in-place operations mpfr needs cannot share the same
22+ * significand for multiple ops (but can have an op repeat).
23+ * So not storeing only those (saving 16 bytes of 48 for a 128 bit number)
24+ * removes the need to worry about this.
2225 */
23- typedef struct {
24- int kind ;
25- mpfr_exp_t exp ;
26- mp_limb_t significand [];
27- } mpf_storage ;
26+ static_assert (_Alignof(mpfr_t ) >= _Alignof(mp_limb_t ),
27+ "mpfr_t storage not aligned as much as limb_t?!" );
28+ typedef mpfr_t mpf_storage ;
2829
2930extern PyArray_DTypeMeta MPFDType ;
3031
3132
3233/*
33- * We currently use this also when init would suffice (to set significand).
34+ * Load into an mpfr_ptr, use a macro which may allow easier changing back
35+ * to a compact storage scheme.
3436 */
3537static inline void
36- mpf_load ( mpfr_t x , char * data_ptr , mpfr_prec_t precision ) {
37- mpf_storage * mpf_ptr = (mpf_storage * )data_ptr ;
38- /* if the kind is 0, reinitialize significand (presumably it never was) */
39- if ( mpf_ptr -> kind == 0 ) {
40- mpfr_custom_init ( mpf_ptr -> significand , precision );
41- mpfr_custom_init_set ( x , MPFR_NAN_KIND , 0 , precision , mpf_ptr -> significand );
42- }
43- else {
44- mpfr_custom_init_set (
45- x , mpf_ptr -> kind , mpf_ptr -> exp , precision , mpf_ptr -> significand );
38+ _mpf_load ( mpfr_ptr * x , char * data_ptr , mpfr_prec_t precision ) {
39+ x [ 0 ] = (mpfr_ptr )data_ptr ;
40+ /*
41+ * We must ensure the signficand is initialized, but NumPy only ensures
42+ * everything is NULL'ed.
43+ */
44+ if ( mpfr_custom_get_significand ( x [ 0 ]) == NULL ) {
45+ void * signficand = data_ptr + sizeof ( mpf_storage );
46+ mpfr_custom_init ( signficand , precision );
47+ mpfr_custom_init_set ( x [ 0 ], MPFR_NAN_KIND , 0 , precision , signficand );
4648 }
4749}
50+ #define mpf_load (x , data_ptr , precision ) _mpf_load(&x, data_ptr, precision)
51+
52+
4853
4954/*
50- * Signficand is always stored, but write back kind and exp
55+ * Not actually required in the current scheme, but keep for now.
56+ * (I had a more compat storage scheme at some point.)
5157 */
5258static inline void
5359mpf_store (char * data_ptr , mpfr_t x ) {
54- mpf_storage * mpf_ptr = (mpf_storage * )data_ptr ;
55- assert (mpfr_custom_get_signficand (x ) == mpf_ptr -> Signficand );
56- mpf_ptr -> kind = mpfr_custom_get_kind (x );
57- mpf_ptr -> exp = mpfr_custom_get_exp (x );
60+ assert (data_ptr == mpfr_t );
5861}
5962
6063
0 commit comments