rightfully states that an mpd_t with a coefficient flagged as MPD_CONST_DATA
must not be in the position of the result operand. In this particular case
several assumptions guarantee that a resize will never occur in all possible
code paths, which was the reason for using MPD_CONST_DATA and saving an
instruction by omitting the initialization of tmp.alloc.
For readability, tmp is now flagged as MPD_STATIC_DATA and tmp.alloc
is initialized.
Resizing is used _inside_ libmpdec functions, and it is permitted to
change x->alloc several times while setting x->len at the end of the
function. Therefore, for dynamic mpd_t x->alloc can _temporarily_ drop
below x->len. Of course the final result always has x->len <= x->alloc.
For static mpd_t this cannot happen, since resizing to a smaller
coefficient is a no-op.
2) Remove micro optimization in mpd_switch_to_dyn(): Previously only the
valid initialized part of the existing coefficient up to x->len was
copied to the new dynamic memory area. Now copying does the same as
realloc() and the entire old memory area is copied.
The rationale for this change is that it is no longer needed to memorize
the explanation given in 1).
2) Assert that the source operand is not special. Prevent resulting assert
failure (harmless) by initializing flags before calling mpd_qshiftr_inplace.
3) Save a couple of instructions (mpd_zerocoeff already sets digits and len).
Reorder initialization to match the order in the mpd_t struct.
in libmpdec to prevent undefined behavior if an invalid context is used. This
cannot occur for the _decimal module since user input for the context is
validated.
with decimal.py. The standard specifies InsufficientStorage (MallocError) as
a sub-condition of InvalidOperation. This allows a calculation to continue
with NaN results when allocation fails.