@@ -3781,6 +3781,43 @@ mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b,
3781
3781
const mpd_context_t * ctx , uint32_t * status )
3782
3782
{
3783
3783
_mpd_qdiv (SET_IDEAL_EXP , q , a , b , ctx , status );
3784
+
3785
+ if (* status & MPD_Malloc_error ) {
3786
+ /* Inexact quotients (the usual case) fill the entire context precision,
3787
+ * which can lead to malloc() failures for very high precisions. Retry
3788
+ * the operation with a lower precision in case the result is exact.
3789
+ *
3790
+ * We need an upper bound for the number of digits of a_coeff / b_coeff
3791
+ * when the result is exact. If a_coeff' * 1 / b_coeff' is in lowest
3792
+ * terms, then maxdigits(a_coeff') + maxdigits(1 / b_coeff') is a suitable
3793
+ * bound.
3794
+ *
3795
+ * 1 / b_coeff' is exact iff b_coeff' exclusively has prime factors 2 or 5.
3796
+ * The largest amount of digits is generated if b_coeff' is a power of 2 or
3797
+ * a power of 5 and is less than or equal to log5(b_coeff') <= log2(b_coeff').
3798
+ *
3799
+ * We arrive at a total upper bound:
3800
+ *
3801
+ * maxdigits(a_coeff') + maxdigits(1 / b_coeff') <=
3802
+ * a->digits + log2(b_coeff) =
3803
+ * a->digits + log10(b_coeff) / log10(2) <=
3804
+ * a->digits + b->digits * 4;
3805
+ */
3806
+ uint32_t workstatus = 0 ;
3807
+ mpd_context_t workctx = * ctx ;
3808
+ workctx .prec = a -> digits + b -> digits * 4 ;
3809
+ if (workctx .prec >= ctx -> prec ) {
3810
+ return ; /* No point in retrying, keep the original error. */
3811
+ }
3812
+
3813
+ _mpd_qdiv (SET_IDEAL_EXP , q , a , b , & workctx , & workstatus );
3814
+ if (workstatus == 0 ) { /* The result is exact, unrounded, normal etc. */
3815
+ * status = 0 ;
3816
+ return ;
3817
+ }
3818
+
3819
+ mpd_seterror (q , * status , status );
3820
+ }
3784
3821
}
3785
3822
3786
3823
/* Internal function. */
@@ -7702,9 +7739,9 @@ mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7702
7739
/* END LIBMPDEC_ONLY */
7703
7740
7704
7741
/* Algorithm from decimal.py */
7705
- void
7706
- mpd_qsqrt (mpd_t * result , const mpd_t * a , const mpd_context_t * ctx ,
7707
- uint32_t * status )
7742
+ static void
7743
+ _mpd_qsqrt (mpd_t * result , const mpd_t * a , const mpd_context_t * ctx ,
7744
+ uint32_t * status )
7708
7745
{
7709
7746
mpd_context_t maxcontext ;
7710
7747
MPD_NEW_STATIC (c ,0 ,0 ,0 ,0 );
@@ -7836,6 +7873,40 @@ mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7836
7873
goto out ;
7837
7874
}
7838
7875
7876
+ void
7877
+ mpd_qsqrt (mpd_t * result , const mpd_t * a , const mpd_context_t * ctx ,
7878
+ uint32_t * status )
7879
+ {
7880
+ _mpd_qsqrt (result , a , ctx , status );
7881
+
7882
+ if (* status & (MPD_Malloc_error |MPD_Division_impossible )) {
7883
+ /* The above conditions can occur at very high context precisions
7884
+ * if intermediate values get too large. Retry the operation with
7885
+ * a lower context precision in case the result is exact.
7886
+ *
7887
+ * If the result is exact, an upper bound for the number of digits
7888
+ * is the number of digits in the input.
7889
+ *
7890
+ * NOTE: sqrt(40e9) = 2.0e+5 /\ digits(40e9) = digits(2.0e+5) = 2
7891
+ */
7892
+ uint32_t workstatus = 0 ;
7893
+ mpd_context_t workctx = * ctx ;
7894
+ workctx .prec = a -> digits ;
7895
+
7896
+ if (workctx .prec >= ctx -> prec ) {
7897
+ return ; /* No point in repeating this, keep the original error. */
7898
+ }
7899
+
7900
+ _mpd_qsqrt (result , a , & workctx , & workstatus );
7901
+ if (workstatus == 0 ) {
7902
+ * status = 0 ;
7903
+ return ;
7904
+ }
7905
+
7906
+ mpd_seterror (result , * status , status );
7907
+ }
7908
+ }
7909
+
7839
7910
7840
7911
/******************************************************************************/
7841
7912
/* Base conversions */
0 commit comments