@@ -97,6 +97,8 @@ static void _settriple(mpd_t *result, uint8_t sign, mpd_uint_t a,
9797 mpd_ssize_t exp );
9898static inline mpd_ssize_t _mpd_real_size (mpd_uint_t * data , mpd_ssize_t size );
9999
100+ static int _mpd_cmp_abs (const mpd_t * a , const mpd_t * b );
101+
100102static void _mpd_qadd (mpd_t * result , const mpd_t * a , const mpd_t * b ,
101103 const mpd_context_t * ctx , uint32_t * status );
102104static inline void _mpd_qmul (mpd_t * result , const mpd_t * a , const mpd_t * b ,
@@ -110,6 +112,17 @@ static inline void _mpd_qpow_uint(mpd_t *result, const mpd_t *base,
110112static mpd_uint_t mpd_qsshiftr (mpd_t * result , const mpd_t * a , mpd_ssize_t n );
111113
112114
115+ /******************************************************************************/
116+ /* Version */
117+ /******************************************************************************/
118+
119+ const char *
120+ mpd_version (void )
121+ {
122+ return MPD_VERSION ;
123+ }
124+
125+
113126/******************************************************************************/
114127/* Performance critical inline functions */
115128/******************************************************************************/
@@ -1345,6 +1358,91 @@ mpd_qget_ssize(const mpd_t *a, uint32_t *status)
13451358 return MPD_SSIZE_MAX ;
13461359}
13471360
1361+ #if defined(CONFIG_32 ) && !defined(LEGACY_COMPILER )
1362+ /*
1363+ * Quietly get a uint64_t from a decimal. If the operation is impossible,
1364+ * MPD_Invalid_operation is set.
1365+ */
1366+ static uint64_t
1367+ _c32_qget_u64 (int use_sign , const mpd_t * a , uint32_t * status )
1368+ {
1369+ MPD_NEW_STATIC (tmp ,0 ,0 ,20 ,3 );
1370+ mpd_context_t maxcontext ;
1371+ uint64_t ret ;
1372+
1373+ tmp_data [0 ] = 709551615 ;
1374+ tmp_data [1 ] = 446744073 ;
1375+ tmp_data [2 ] = 18 ;
1376+
1377+ if (mpd_isspecial (a )) {
1378+ * status |= MPD_Invalid_operation ;
1379+ return UINT64_MAX ;
1380+ }
1381+ if (mpd_iszero (a )) {
1382+ return 0 ;
1383+ }
1384+ if (use_sign && mpd_isnegative (a )) {
1385+ * status |= MPD_Invalid_operation ;
1386+ return UINT64_MAX ;
1387+ }
1388+ if (!_mpd_isint (a )) {
1389+ * status |= MPD_Invalid_operation ;
1390+ return UINT64_MAX ;
1391+ }
1392+
1393+ if (_mpd_cmp_abs (a , & tmp ) > 0 ) {
1394+ * status |= MPD_Invalid_operation ;
1395+ return UINT64_MAX ;
1396+ }
1397+
1398+ mpd_maxcontext (& maxcontext );
1399+ mpd_qrescale (& tmp , a , 0 , & maxcontext , & maxcontext .status );
1400+ maxcontext .status &= ~MPD_Rounded ;
1401+ if (maxcontext .status != 0 ) {
1402+ * status |= (maxcontext .status |MPD_Invalid_operation ); /* GCOV_NOT_REACHED */
1403+ return UINT64_MAX ; /* GCOV_NOT_REACHED */
1404+ }
1405+
1406+ ret = 0 ;
1407+ switch (tmp .len ) {
1408+ case 3 :
1409+ ret += (uint64_t )tmp_data [2 ] * 1000000000000000000ULL ;
1410+ case 2 :
1411+ ret += (uint64_t )tmp_data [1 ] * 1000000000ULL ;
1412+ case 1 :
1413+ ret += tmp_data [0 ];
1414+ break ;
1415+ default :
1416+ abort (); /* GCOV_NOT_REACHED */
1417+ }
1418+
1419+ return ret ;
1420+ }
1421+
1422+ static int64_t
1423+ _c32_qget_i64 (const mpd_t * a , uint32_t * status )
1424+ {
1425+ uint64_t u ;
1426+ int isneg ;
1427+
1428+ u = _c32_qget_u64 (0 , a , status );
1429+ if (* status & MPD_Invalid_operation ) {
1430+ return INT64_MAX ;
1431+ }
1432+
1433+ isneg = mpd_isnegative (a );
1434+ if (u <= INT64_MAX ) {
1435+ return isneg ? - ((int64_t )u ) : (int64_t )u ;
1436+ }
1437+ else if (isneg && u + (INT64_MIN + INT64_MAX ) == INT64_MAX ) {
1438+ return INT64_MIN ;
1439+ }
1440+
1441+ * status |= MPD_Invalid_operation ;
1442+ return INT64_MAX ;
1443+ }
1444+ #endif /* CONFIG_32 && !LEGACY_COMPILER */
1445+
13481446#ifdef CONFIG_64
13491447/* quietly get a uint64_t from a decimal */
13501448uint64_t
@@ -1359,7 +1457,57 @@ mpd_qget_i64(const mpd_t *a, uint32_t *status)
13591457{
13601458 return mpd_qget_ssize (a , status );
13611459}
1460+
1461+ /* quietly get a uint32_t from a decimal */
1462+ uint32_t
1463+ mpd_qget_u32 (const mpd_t * a , uint32_t * status )
1464+ {
1465+ uint64_t x = mpd_qget_uint (a , status );
1466+
1467+ if (* status & MPD_Invalid_operation ) {
1468+ return UINT32_MAX ;
1469+ }
1470+ if (x > UINT32_MAX ) {
1471+ * status |= MPD_Invalid_operation ;
1472+ return UINT32_MAX ;
1473+ }
1474+
1475+ return (uint32_t )x ;
1476+ }
1477+
1478+ /* quietly get an int32_t from a decimal */
1479+ int32_t
1480+ mpd_qget_i32 (const mpd_t * a , uint32_t * status )
1481+ {
1482+ int64_t x = mpd_qget_ssize (a , status );
1483+
1484+ if (* status & MPD_Invalid_operation ) {
1485+ return INT32_MAX ;
1486+ }
1487+ if (x < INT32_MIN || x > INT32_MAX ) {
1488+ * status |= MPD_Invalid_operation ;
1489+ return INT32_MAX ;
1490+ }
1491+
1492+ return (int32_t )x ;
1493+ }
13621494#else
1495+ #ifndef LEGACY_COMPILER
1496+ /* quietly get a uint64_t from a decimal */
1497+ uint64_t
1498+ mpd_qget_u64 (const mpd_t * a , uint32_t * status )
1499+ {
1500+ return _c32_qget_u64 (1 , a , status );
1501+ }
1502+
1503+ /* quietly get an int64_t from a decimal */
1504+ int64_t
1505+ mpd_qget_i64 (const mpd_t * a , uint32_t * status )
1506+ {
1507+ return _c32_qget_i64 (a , status );
1508+ }
1509+ #endif
1510+
13631511/* quietly get a uint32_t from a decimal */
13641512uint32_t
13651513mpd_qget_u32 (const mpd_t * a , uint32_t * status )
@@ -3386,6 +3534,34 @@ mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b,
33863534{
33873535 mpd_qadd_uint (result , a , b , ctx , status );
33883536}
3537+ #elif !defined(LEGACY_COMPILER )
3538+ /* Add decimal and int64_t. */
3539+ void
3540+ mpd_qadd_i64 (mpd_t * result , const mpd_t * a , int64_t b ,
3541+ const mpd_context_t * ctx , uint32_t * status )
3542+ {
3543+ mpd_context_t maxcontext ;
3544+ MPD_NEW_STATIC (bb ,0 ,0 ,0 ,0 );
3545+
3546+ mpd_maxcontext (& maxcontext );
3547+ mpd_qset_i64 (& bb , b , & maxcontext , status );
3548+ mpd_qadd (result , a , & bb , ctx , status );
3549+ mpd_del (& bb );
3550+ }
3551+
3552+ /* Add decimal and uint64_t. */
3553+ void
3554+ mpd_qadd_u64 (mpd_t * result , const mpd_t * a , uint64_t b ,
3555+ const mpd_context_t * ctx , uint32_t * status )
3556+ {
3557+ mpd_context_t maxcontext ;
3558+ MPD_NEW_STATIC (bb ,0 ,0 ,0 ,0 );
3559+
3560+ mpd_maxcontext (& maxcontext );
3561+ mpd_qset_u64 (& bb , b , & maxcontext , status );
3562+ mpd_qadd (result , a , & bb , ctx , status );
3563+ mpd_del (& bb );
3564+ }
33893565#endif
33903566
33913567/* Subtract int32_t from decimal. */
@@ -3420,6 +3596,34 @@ mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b,
34203596{
34213597 mpd_qsub_uint (result , a , b , ctx , status );
34223598}
3599+ #elif !defined(LEGACY_COMPILER )
3600+ /* Subtract int64_t from decimal. */
3601+ void
3602+ mpd_qsub_i64 (mpd_t * result , const mpd_t * a , int64_t b ,
3603+ const mpd_context_t * ctx , uint32_t * status )
3604+ {
3605+ mpd_context_t maxcontext ;
3606+ MPD_NEW_STATIC (bb ,0 ,0 ,0 ,0 );
3607+
3608+ mpd_maxcontext (& maxcontext );
3609+ mpd_qset_i64 (& bb , b , & maxcontext , status );
3610+ mpd_qsub (result , a , & bb , ctx , status );
3611+ mpd_del (& bb );
3612+ }
3613+
3614+ /* Subtract uint64_t from decimal. */
3615+ void
3616+ mpd_qsub_u64 (mpd_t * result , const mpd_t * a , uint64_t b ,
3617+ const mpd_context_t * ctx , uint32_t * status )
3618+ {
3619+ mpd_context_t maxcontext ;
3620+ MPD_NEW_STATIC (bb ,0 ,0 ,0 ,0 );
3621+
3622+ mpd_maxcontext (& maxcontext );
3623+ mpd_qset_u64 (& bb , b , & maxcontext , status );
3624+ mpd_qsub (result , a , & bb , ctx , status );
3625+ mpd_del (& bb );
3626+ }
34233627#endif
34243628
34253629
@@ -3871,6 +4075,34 @@ mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b,
38714075{
38724076 mpd_qdiv_uint (result , a , b , ctx , status );
38734077}
4078+ #elif !defined(LEGACY_COMPILER )
4079+ /* Divide decimal by int64_t. */
4080+ void
4081+ mpd_qdiv_i64 (mpd_t * result , const mpd_t * a , int64_t b ,
4082+ const mpd_context_t * ctx , uint32_t * status )
4083+ {
4084+ mpd_context_t maxcontext ;
4085+ MPD_NEW_STATIC (bb ,0 ,0 ,0 ,0 );
4086+
4087+ mpd_maxcontext (& maxcontext );
4088+ mpd_qset_i64 (& bb , b , & maxcontext , status );
4089+ mpd_qdiv (result , a , & bb , ctx , status );
4090+ mpd_del (& bb );
4091+ }
4092+
4093+ /* Divide decimal by uint64_t. */
4094+ void
4095+ mpd_qdiv_u64 (mpd_t * result , const mpd_t * a , uint64_t b ,
4096+ const mpd_context_t * ctx , uint32_t * status )
4097+ {
4098+ mpd_context_t maxcontext ;
4099+ MPD_NEW_STATIC (bb ,0 ,0 ,0 ,0 );
4100+
4101+ mpd_maxcontext (& maxcontext );
4102+ mpd_qset_u64 (& bb , b , & maxcontext , status );
4103+ mpd_qdiv (result , a , & bb , ctx , status );
4104+ mpd_del (& bb );
4105+ }
38744106#endif
38754107
38764108/* Pad the result with trailing zeros if it has fewer digits than prec. */
@@ -5664,6 +5896,34 @@ mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b,
56645896{
56655897 mpd_qmul_uint (result , a , b , ctx , status );
56665898}
5899+ #elif !defined(LEGACY_COMPILER )
5900+ /* Multiply decimal and int64_t. */
5901+ void
5902+ mpd_qmul_i64 (mpd_t * result , const mpd_t * a , int64_t b ,
5903+ const mpd_context_t * ctx , uint32_t * status )
5904+ {
5905+ mpd_context_t maxcontext ;
5906+ MPD_NEW_STATIC (bb ,0 ,0 ,0 ,0 );
5907+
5908+ mpd_maxcontext (& maxcontext );
5909+ mpd_qset_i64 (& bb , b , & maxcontext , status );
5910+ mpd_qmul (result , a , & bb , ctx , status );
5911+ mpd_del (& bb );
5912+ }
5913+
5914+ /* Multiply decimal and uint64_t. */
5915+ void
5916+ mpd_qmul_u64 (mpd_t * result , const mpd_t * a , uint64_t b ,
5917+ const mpd_context_t * ctx , uint32_t * status )
5918+ {
5919+ mpd_context_t maxcontext ;
5920+ MPD_NEW_STATIC (bb ,0 ,0 ,0 ,0 );
5921+
5922+ mpd_maxcontext (& maxcontext );
5923+ mpd_qset_u64 (& bb , b , & maxcontext , status );
5924+ mpd_qmul (result , a , & bb , ctx , status );
5925+ mpd_del (& bb );
5926+ }
56675927#endif
56685928
56695929/* Like the minus operator. */
0 commit comments