@@ -3639,12 +3639,13 @@ dec_format(PyObject *dec, PyObject *args)
36393639static PyObject *
36403640dec_as_long (PyObject * dec , PyObject * context , int round )
36413641{
3642- PyLongObject * pylong ;
3642+ PyObject * pylong ;
36433643 digit * ob_digit ;
36443644 size_t n ;
36453645 mpd_t * x ;
36463646 mpd_context_t workctx ;
36473647 uint32_t status = 0 ;
3648+ const PyLongLayout * layout = PyLong_GetNativeLayout ();
36483649
36493650 if (mpd_isspecial (MPD (dec ))) {
36503651 if (mpd_isnan (MPD (dec ))) {
@@ -3672,34 +3673,45 @@ dec_as_long(PyObject *dec, PyObject *context, int round)
36723673 }
36733674
36743675 status = 0 ;
3675- ob_digit = NULL ;
3676+
3677+ int64_t val = mpd_qget_i64 (x , & status );
3678+ if (!status ) {
3679+ mpd_del (x );
3680+ return PyLong_FromInt64 (val );
3681+ }
3682+
3683+ n = (mpd_sizeinbase (x , 2 ) +
3684+ layout -> bits_per_digit - 1 ) / layout -> bits_per_digit ;
3685+ PyLongWriter * writer = PyLongWriter_Create (mpd_isnegative (x ), n ,
3686+ (void * * )& ob_digit );
3687+ /* mpd_sizeinbase can overestimate size by 1 digit, set it to zero. */
3688+ ob_digit [n - 1 ] = 0 ;
3689+ if (writer == NULL ) {
3690+ PyLongWriter_Discard (writer );
3691+ mpd_del (x );
3692+ return NULL ;
3693+ }
3694+
3695+ status = 0 ;
36763696#if PYLONG_BITS_IN_DIGIT == 30
3677- n = mpd_qexport_u32 (& ob_digit , 0 , PyLong_BASE , x , & status );
3697+ n = mpd_qexport_u32 (& ob_digit , n , PyLong_BASE , x , & status );
36783698#elif PYLONG_BITS_IN_DIGIT == 15
3679- n = mpd_qexport_u16 (& ob_digit , 0 , PyLong_BASE , x , & status );
3699+ n = mpd_qexport_u16 (& ob_digit , n , PyLong_BASE , x , & status );
36803700#else
36813701 #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
36823702#endif
36833703
36843704 if (n == SIZE_MAX ) {
36853705 PyErr_NoMemory ();
3706+ PyLongWriter_Discard (writer );
36863707 mpd_del (x );
36873708 return NULL ;
36883709 }
36893710
3690- if (n == 1 ) {
3691- sdigit val = mpd_arith_sign (x ) * ob_digit [0 ];
3692- mpd_free (ob_digit );
3693- mpd_del (x );
3694- return PyLong_FromLong (val );
3695- }
3696-
36973711 assert (n > 0 );
3698- assert (!mpd_iszero (x ));
3699- pylong = _PyLong_FromDigits (mpd_isnegative (x ), n , ob_digit );
3700- mpd_free (ob_digit );
3712+ pylong = PyLongWriter_Finish (writer );
37013713 mpd_del (x );
3702- return ( PyObject * ) pylong ;
3714+ return pylong ;
37033715}
37043716
37053717/* Convert a Decimal to its exact integer ratio representation. */
0 commit comments