[Python-checkins] bpo-41369: Finish updating the vendored libmpdec to version 2.5.1 (GH-24962)

pitrou webhook-mailer at python.org
Tue Mar 30 12:11:30 EDT 2021


https://github.com/python/cpython/commit/73b20ae2fb7a5c1374aa5c3719f64c53d29fa0d2
commit: 73b20ae2fb7a5c1374aa5c3719f64c53d29fa0d2
branch: master
author: Antoine Pitrou <antoine at python.org>
committer: pitrou <pitrou at free.fr>
date: 2021-03-30T18:11:06+02:00
summary:

bpo-41369: Finish updating the vendored libmpdec to version 2.5.1 (GH-24962)

Complete the update to libmpdec-2.5.1.

Co-authored-by: Stefan Krah <skrah at bytereef.org>

files:
A Misc/NEWS.d/next/Library/2021-03-21-17-50-42.bpo-41369.-fpmYZ.rst
A Modules/_decimal/libmpdec/bench.c
A Modules/_decimal/libmpdec/bench_full.c
A Modules/_decimal/libmpdec/examples/README.txt
A Modules/_decimal/libmpdec/examples/compare.c
A Modules/_decimal/libmpdec/examples/div.c
A Modules/_decimal/libmpdec/examples/divmod.c
A Modules/_decimal/libmpdec/examples/multiply.c
A Modules/_decimal/libmpdec/examples/pow.c
A Modules/_decimal/libmpdec/examples/powmod.c
A Modules/_decimal/libmpdec/examples/shift.c
A Modules/_decimal/libmpdec/examples/sqrt.c
A Modules/_decimal/libmpdec/mpsignal.c
D Modules/_decimal/libmpdec/vccompat.h
M Modules/_decimal/_decimal.c
M Modules/_decimal/libmpdec/README.txt
M Modules/_decimal/libmpdec/constants.c
M Modules/_decimal/libmpdec/context.c
M Modules/_decimal/libmpdec/crt.c
M Modules/_decimal/libmpdec/crt.h
M Modules/_decimal/libmpdec/io.c
M Modules/_decimal/libmpdec/mpalloc.c
M Modules/_decimal/libmpdec/mpalloc.h
M Modules/_decimal/libmpdec/mpdecimal.c
M Modules/_decimal/libmpdec/mpdecimal.h
M Modules/_decimal/libmpdec/typearith.h
M setup.py

diff --git a/Misc/NEWS.d/next/Library/2021-03-21-17-50-42.bpo-41369.-fpmYZ.rst b/Misc/NEWS.d/next/Library/2021-03-21-17-50-42.bpo-41369.-fpmYZ.rst
new file mode 100644
index 0000000000000..6a85e8259cef4
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-03-21-17-50-42.bpo-41369.-fpmYZ.rst
@@ -0,0 +1,2 @@
+Finish updating the vendored libmpdec to version 2.5.1.  Patch by Stefan
+Krah.
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index 83e237d02bf5a..9a4329f494f31 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -3293,7 +3293,7 @@ dec_format(PyObject *dec, PyObject *args)
     }
     else {
         size_t n = strlen(spec.dot);
-        if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) {
+        if (n > 1 || (n == 1 && !isascii((unsigned char)spec.dot[0]))) {
             /* fix locale dependent non-ascii characters */
             dot = dotsep_as_utf8(spec.dot);
             if (dot == NULL) {
@@ -3302,7 +3302,7 @@ dec_format(PyObject *dec, PyObject *args)
             spec.dot = PyBytes_AS_STRING(dot);
         }
         n = strlen(spec.sep);
-        if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) {
+        if (n > 1 || (n == 1 && !isascii((unsigned char)spec.sep[0]))) {
             /* fix locale dependent non-ascii characters */
             sep = dotsep_as_utf8(spec.sep);
             if (sep == NULL) {
diff --git a/Modules/_decimal/libmpdec/README.txt b/Modules/_decimal/libmpdec/README.txt
index dc97820a6eb0c..c1d481dee7645 100644
--- a/Modules/_decimal/libmpdec/README.txt
+++ b/Modules/_decimal/libmpdec/README.txt
@@ -29,7 +29,6 @@ Files required for the Python _decimal module
 
     Visual Studio only:
     ~~~~~~~~~~~~~~~~~~~
-      vccompat.h    ->  snprintf <==> sprintf_s and similar things.
       vcdiv64.asm   ->  Double word division used in typearith.h. VS 2008 does
                         not allow inline asm for x64. Also, it does not provide
                         an intrinsic for double word division.
diff --git a/Modules/_decimal/libmpdec/bench.c b/Modules/_decimal/libmpdec/bench.c
new file mode 100644
index 0000000000000..09138f4ce9c03
--- /dev/null
+++ b/Modules/_decimal/libmpdec/bench.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include "mpdecimal.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+
+static void
+err_exit(const char *msg)
+{
+    fprintf(stderr, "%s\n", msg);
+    exit(1);
+}
+
+static mpd_t *
+new_mpd(void)
+{
+    mpd_t *x = mpd_qnew();
+    if (x == NULL) {
+        err_exit("out of memory");
+    }
+
+    return x;
+}
+
+/* Nonsense version of escape-time algorithm for calculating a mandelbrot
+ * set. Just for benchmarking. */
+static void
+color_point(mpd_t *x0, mpd_t *y0, long maxiter, mpd_context_t *ctx)
+{
+    mpd_t *x, *y, *sq_x, *sq_y;
+    mpd_t *two;
+
+    x = new_mpd();
+    y = new_mpd();
+    mpd_set_u32(x, 0, ctx);
+    mpd_set_u32(y, 0, ctx);
+
+    sq_x = new_mpd();
+    sq_y = new_mpd();
+    mpd_set_u32(sq_x, 0, ctx);
+    mpd_set_u32(sq_y, 0, ctx);
+
+    two = new_mpd();
+    mpd_set_u32(two, 2, ctx);
+
+    for (long i = 0; i < maxiter; i++) {
+        mpd_mul(y, x, y, ctx);
+        mpd_mul(y, y, two, ctx);
+        mpd_add(y, y, y0, ctx);
+
+        mpd_sub(x, sq_x, sq_y, ctx);
+        mpd_add(x, x, x0, ctx);
+
+        mpd_mul(sq_x, x, x, ctx);
+        mpd_mul(sq_y, y, y, ctx);
+    }
+
+    mpd_copy(x0, x, ctx);
+
+    mpd_del(two);
+    mpd_del(sq_y);
+    mpd_del(sq_x);
+    mpd_del(y);
+    mpd_del(x);
+}
+
+
+int
+main(int argc, char **argv)
+{
+    mpd_context_t ctx;
+    mpd_t *x0, *y0;
+    uint32_t prec = 19;
+    long iter = 10000000;
+    clock_t start_clock, end_clock;
+
+    if (argc != 3) {
+        err_exit("usage: bench prec iter\n");
+    }
+    prec = strtoul(argv[1], NULL, 10);
+    iter = strtol(argv[2], NULL, 10);
+
+    mpd_init(&ctx, prec);
+    /* no more MPD_MINALLOC changes after here */
+
+    x0 = new_mpd();
+    y0 = new_mpd();
+    mpd_set_string(x0, "0.222", &ctx);
+    mpd_set_string(y0, "0.333", &ctx);
+    if (ctx.status & MPD_Errors) {
+        mpd_del(y0);
+        mpd_del(x0);
+        err_exit("unexpected error during conversion");
+    }
+
+    start_clock = clock();
+    color_point(x0, y0, iter, &ctx);
+    end_clock = clock();
+
+    mpd_print(x0);
+    fprintf(stderr, "time: %f\n\n", (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
+
+    mpd_del(y0);
+    mpd_del(x0);
+
+    return 0;
+}
diff --git a/Modules/_decimal/libmpdec/bench_full.c b/Modules/_decimal/libmpdec/bench_full.c
new file mode 100644
index 0000000000000..6ab73917e1c32
--- /dev/null
+++ b/Modules/_decimal/libmpdec/bench_full.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include "mpdecimal.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+
+static void
+err_exit(const char *msg)
+{
+    fprintf(stderr, "%s\n", msg);
+    exit(1);
+}
+
+static mpd_t *
+new_mpd(void)
+{
+    mpd_t *x = mpd_qnew();
+    if (x == NULL) {
+        err_exit("out of memory");
+    }
+
+    return x;
+}
+
+/*
+ * Example from: http://en.wikipedia.org/wiki/Mandelbrot_set
+ *
+ * Escape time algorithm for drawing the set:
+ *
+ * Point x0, y0 is deemed to be in the Mandelbrot set if the return
+ * value is maxiter. Lower return values indicate how quickly points
+ * escaped and can be used for coloring.
+ */
+static int
+color_point(const mpd_t *x0, const mpd_t *y0, const long maxiter, mpd_context_t *ctx)
+{
+    mpd_t *x, *y, *sq_x, *sq_y;
+    mpd_t *two, *four, *c;
+    long i;
+
+    x = new_mpd();
+    y = new_mpd();
+    mpd_set_u32(x, 0, ctx);
+    mpd_set_u32(y, 0, ctx);
+
+    sq_x = new_mpd();
+    sq_y = new_mpd();
+    mpd_set_u32(sq_x, 0, ctx);
+    mpd_set_u32(sq_y, 0, ctx);
+
+    two = new_mpd();
+    four = new_mpd();
+    mpd_set_u32(two, 2, ctx);
+    mpd_set_u32(four, 4, ctx);
+
+    c = new_mpd();
+    mpd_set_u32(c, 0, ctx);
+
+    for (i = 0; i < maxiter && mpd_cmp(c, four, ctx) <= 0; i++) {
+        mpd_mul(y, x, y, ctx);
+        mpd_mul(y, y, two, ctx);
+        mpd_add(y, y, y0, ctx);
+
+        mpd_sub(x, sq_x, sq_y, ctx);
+        mpd_add(x, x, x0, ctx);
+
+        mpd_mul(sq_x, x, x, ctx);
+        mpd_mul(sq_y, y, y, ctx);
+        mpd_add(c, sq_x, sq_y, ctx);
+    }
+
+    mpd_del(c);
+    mpd_del(four);
+    mpd_del(two);
+    mpd_del(sq_y);
+    mpd_del(sq_x);
+    mpd_del(y);
+    mpd_del(x);
+
+    return i;
+}
+
+int
+main(int argc, char **argv)
+{
+    mpd_context_t ctx;
+    mpd_t *x0, *y0;
+    mpd_t *sqrt_2, *xstep, *ystep;
+    mpd_ssize_t prec = 19;
+
+    long iter = 1000;
+    int points[40][80];
+    int i, j;
+    clock_t start_clock, end_clock;
+
+
+    if (argc != 3) {
+        fprintf(stderr, "usage: ./bench prec iter\n");
+        exit(1);
+    }
+    prec = strtoll(argv[1], NULL, 10);
+    iter = strtol(argv[2], NULL, 10);
+
+    mpd_init(&ctx, prec);
+    /* no more MPD_MINALLOC changes after here */
+
+    sqrt_2 = new_mpd();
+    xstep = new_mpd();
+    ystep = new_mpd();
+    x0 = new_mpd();
+    y0 = new_mpd();
+
+    mpd_set_u32(sqrt_2, 2, &ctx);
+    mpd_sqrt(sqrt_2, sqrt_2, &ctx);
+    mpd_div_u32(xstep, sqrt_2, 40, &ctx);
+    mpd_div_u32(ystep, sqrt_2, 20, &ctx);
+
+    start_clock = clock();
+    mpd_copy(y0, sqrt_2, &ctx);
+    for (i = 0; i < 40; i++) {
+        mpd_copy(x0, sqrt_2, &ctx);
+        mpd_set_negative(x0);
+        for (j = 0; j < 80; j++) {
+            points[i][j] = color_point(x0, y0, iter, &ctx);
+            mpd_add(x0, x0, xstep, &ctx);
+        }
+        mpd_sub(y0, y0, ystep, &ctx);
+    }
+    end_clock = clock();
+
+#ifdef BENCH_VERBOSE
+    for (i = 0; i < 40; i++) {
+        for (j = 0; j < 80; j++) {
+            if (points[i][j] == iter) {
+                putchar('*');
+            }
+            else if (points[i][j] >= 10) {
+                putchar('+');
+            }
+            else if (points[i][j] >= 5) {
+                putchar('.');
+            }
+            else {
+                putchar(' ');
+            }
+        }
+        putchar('\n');
+    }
+    putchar('\n');
+#else
+    (void)points; /* suppress gcc warning */
+#endif
+
+    printf("time: %f\n\n", (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
+
+    mpd_del(y0);
+    mpd_del(x0);
+    mpd_del(ystep);
+    mpd_del(xstep);
+    mpd_del(sqrt_2);
+
+    return 0;
+}
diff --git a/Modules/_decimal/libmpdec/constants.c b/Modules/_decimal/libmpdec/constants.c
index 4c4de622bc601..ed074fa81c6d2 100644
--- a/Modules/_decimal/libmpdec/constants.c
+++ b/Modules/_decimal/libmpdec/constants.c
@@ -27,6 +27,7 @@
 
 
 #include "mpdecimal.h"
+#include "basearith.h"
 #include "constants.h"
 
 
@@ -111,7 +112,7 @@
   #error "CONFIG_64 or CONFIG_32 must be defined."
 #endif
 
-const char *mpd_round_string[MPD_ROUND_GUARD] = {
+const char * const mpd_round_string[MPD_ROUND_GUARD] = {
     "ROUND_UP",          /* round away from 0               */
     "ROUND_DOWN",        /* round toward 0 (truncate)       */
     "ROUND_CEILING",     /* round toward +infinity          */
@@ -123,7 +124,7 @@ const char *mpd_round_string[MPD_ROUND_GUARD] = {
     "ROUND_TRUNC",       /* truncate, but set infinity      */
 };
 
-const char *mpd_clamp_string[MPD_CLAMP_GUARD] = {
+const char * const mpd_clamp_string[MPD_CLAMP_GUARD] = {
     "CLAMP_DEFAULT",
     "CLAMP_IEEE_754"
 };
diff --git a/Modules/_decimal/libmpdec/context.c b/Modules/_decimal/libmpdec/context.c
index 9cbc20509595d..172794b67d800 100644
--- a/Modules/_decimal/libmpdec/context.c
+++ b/Modules/_decimal/libmpdec/context.c
@@ -235,12 +235,12 @@ mpd_qsetround(mpd_context_t *ctx, int round)
 }
 
 int
-mpd_qsettraps(mpd_context_t *ctx, uint32_t traps)
+mpd_qsettraps(mpd_context_t *ctx, uint32_t flags)
 {
-    if (traps > MPD_Max_status) {
+    if (flags > MPD_Max_status) {
         return 0;
     }
-    ctx->traps = traps;
+    ctx->traps = flags;
     return 1;
 }
 
diff --git a/Modules/_decimal/libmpdec/crt.c b/Modules/_decimal/libmpdec/crt.c
index 613274ee0c5b5..babcce41bf67c 100644
--- a/Modules/_decimal/libmpdec/crt.c
+++ b/Modules/_decimal/libmpdec/crt.c
@@ -33,8 +33,8 @@
 #include "constants.h"
 #include "crt.h"
 #include "numbertheory.h"
-#include "umodarith.h"
 #include "typearith.h"
+#include "umodarith.h"
 
 
 /* Bignum: Chinese Remainder Theorem, extends the maximum transform length. */
@@ -62,17 +62,17 @@ static inline void
 _crt_add3(mpd_uint_t w[3], mpd_uint_t v[3])
 {
     mpd_uint_t carry;
-    mpd_uint_t s;
 
-    s = w[0] + v[0];
-    carry = (s < w[0]);
-    w[0] = s;
+    w[0] = w[0] + v[0];
+    carry = (w[0] < v[0]);
+
+    w[1] = w[1] + v[1];
+    if (w[1] < v[1]) w[2]++;
 
-    s = w[1] + (v[1] + carry);
-    carry = (s < w[1]);
-    w[1] = s;
+    w[1] = w[1] + carry;
+    if (w[1] < carry) w[2]++;
 
-    w[2] = w[2] + (v[2] + carry);
+    w[2] += v[2];
 }
 
 /* Divide 3 words in u by v, store result in w, return remainder. */
diff --git a/Modules/_decimal/libmpdec/crt.h b/Modules/_decimal/libmpdec/crt.h
index 15a347d4cb31e..ed66753c2510b 100644
--- a/Modules/_decimal/libmpdec/crt.h
+++ b/Modules/_decimal/libmpdec/crt.h
@@ -37,7 +37,7 @@
 MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
 
 
-void crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t nmemb);
+void crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t rsize);
 
 
 MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
diff --git a/Modules/_decimal/libmpdec/examples/README.txt b/Modules/_decimal/libmpdec/examples/README.txt
new file mode 100644
index 0000000000000..69615b45f9821
--- /dev/null
+++ b/Modules/_decimal/libmpdec/examples/README.txt
@@ -0,0 +1,8 @@
+
+
+This directory contains a number of examples. In order to compile, run
+(for example):
+
+gcc -Wall -W -O2 -o powmod powmod.c -lmpdec -lm
+
+
diff --git a/Modules/_decimal/libmpdec/examples/compare.c b/Modules/_decimal/libmpdec/examples/compare.c
new file mode 100644
index 0000000000000..9051773e116de
--- /dev/null
+++ b/Modules/_decimal/libmpdec/examples/compare.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <mpdecimal.h>
+
+
+int
+main(int argc, char **argv)
+{
+	mpd_context_t ctx;
+	mpd_t *a, *b;
+	mpd_t *result;
+	char *rstring;
+	char status_str[MPD_MAX_FLAG_STRING];
+	clock_t start_clock, end_clock;
+
+	if (argc != 3) {
+		fprintf(stderr, "compare: usage: ./compare x y\n");
+		exit(1);
+	}
+
+	mpd_init(&ctx, 38);
+	ctx.traps = 0;
+
+	result = mpd_new(&ctx);
+	a = mpd_new(&ctx);
+	b = mpd_new(&ctx);
+	mpd_set_string(a, argv[1], &ctx);
+	mpd_set_string(b, argv[2], &ctx);
+
+	start_clock = clock();
+	mpd_compare(result, a, b, &ctx);
+	end_clock = clock();
+	fprintf(stderr, "time: %f\n\n",
+	           (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
+
+	rstring = mpd_to_sci(result, 1);
+	mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status);
+	printf("%s  %s\n", rstring, status_str);
+
+	mpd_del(a);
+	mpd_del(b);
+	mpd_del(result);
+	mpd_free(rstring);
+
+	return 0;
+}
+
+
diff --git a/Modules/_decimal/libmpdec/examples/div.c b/Modules/_decimal/libmpdec/examples/div.c
new file mode 100644
index 0000000000000..b76037d2a64c6
--- /dev/null
+++ b/Modules/_decimal/libmpdec/examples/div.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <mpdecimal.h>
+
+
+int
+main(int argc, char **argv)
+{
+	mpd_context_t ctx;
+	mpd_t *a, *b;
+	mpd_t *result;
+	char *rstring;
+	char status_str[MPD_MAX_FLAG_STRING];
+	clock_t start_clock, end_clock;
+
+	if (argc != 3) {
+		fprintf(stderr, "div: usage: ./div x y\n");
+		exit(1);
+	}
+
+	mpd_init(&ctx, 38);
+	ctx.traps = 0;
+
+	result = mpd_new(&ctx);
+	a = mpd_new(&ctx);
+	b = mpd_new(&ctx);
+	mpd_set_string(a, argv[1], &ctx);
+	mpd_set_string(b, argv[2], &ctx);
+
+	start_clock = clock();
+	mpd_div(result, a, b, &ctx);
+	end_clock = clock();
+	fprintf(stderr, "time: %f\n\n",
+	           (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
+
+	rstring = mpd_to_sci(result, 1);
+	mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status);
+	printf("%s  %s\n", rstring, status_str);
+
+	mpd_del(a);
+	mpd_del(b);
+	mpd_del(result);
+	mpd_free(rstring);
+
+	return 0;
+}
+
+
diff --git a/Modules/_decimal/libmpdec/examples/divmod.c b/Modules/_decimal/libmpdec/examples/divmod.c
new file mode 100644
index 0000000000000..1f2b48306d6d0
--- /dev/null
+++ b/Modules/_decimal/libmpdec/examples/divmod.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <mpdecimal.h>
+
+
+int
+main(int argc, char **argv)
+{
+	mpd_context_t ctx;
+	mpd_t *a, *b;
+	mpd_t *q, *r;
+	char *qs, *rs;
+	char status_str[MPD_MAX_FLAG_STRING];
+	clock_t start_clock, end_clock;
+
+	if (argc != 3) {
+		fprintf(stderr, "divmod: usage: ./divmod x y\n");
+		exit(1);
+	}
+
+	mpd_init(&ctx, 38);
+	ctx.traps = 0;
+
+	q = mpd_new(&ctx);
+	r = mpd_new(&ctx);
+	a = mpd_new(&ctx);
+	b = mpd_new(&ctx);
+	mpd_set_string(a, argv[1], &ctx);
+	mpd_set_string(b, argv[2], &ctx);
+
+	start_clock = clock();
+	mpd_divmod(q, r, a, b, &ctx);
+	end_clock = clock();
+	fprintf(stderr, "time: %f\n\n",
+	           (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
+
+	qs = mpd_to_sci(q, 1);
+	rs = mpd_to_sci(r, 1);
+
+	mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status);
+	printf("%s  %s  %s\n", qs, rs, status_str);
+
+	mpd_del(q);
+	mpd_del(r);
+	mpd_del(a);
+	mpd_del(b);
+	mpd_free(qs);
+	mpd_free(rs);
+
+	return 0;
+}
+
+
diff --git a/Modules/_decimal/libmpdec/examples/multiply.c b/Modules/_decimal/libmpdec/examples/multiply.c
new file mode 100644
index 0000000000000..7f2687d15f827
--- /dev/null
+++ b/Modules/_decimal/libmpdec/examples/multiply.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <mpdecimal.h>
+
+
+int
+main(int argc, char **argv)
+{
+	mpd_context_t ctx;
+	mpd_t *a, *b;
+	mpd_t *result;
+	char *rstring;
+	char status_str[MPD_MAX_FLAG_STRING];
+	clock_t start_clock, end_clock;
+
+	if (argc != 3) {
+		fprintf(stderr, "multiply: usage: ./multiply x y\n");
+		exit(1);
+	}
+
+	mpd_init(&ctx, 38);
+	ctx.traps = 0;
+
+	result = mpd_new(&ctx);
+	a = mpd_new(&ctx);
+	b = mpd_new(&ctx);
+	mpd_set_string(a, argv[1], &ctx);
+	mpd_set_string(b, argv[2], &ctx);
+
+	start_clock = clock();
+	mpd_mul(result, a, b, &ctx);
+	end_clock = clock();
+	fprintf(stderr, "time: %f\n\n",
+	           (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
+
+	rstring = mpd_to_sci(result, 1);
+	mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status);
+	printf("%s  %s\n", rstring, status_str);
+
+	mpd_del(a);
+	mpd_del(b);
+	mpd_del(result);
+	mpd_free(rstring);
+
+	return 0;
+}
+
+
diff --git a/Modules/_decimal/libmpdec/examples/pow.c b/Modules/_decimal/libmpdec/examples/pow.c
new file mode 100644
index 0000000000000..628c143427357
--- /dev/null
+++ b/Modules/_decimal/libmpdec/examples/pow.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <mpdecimal.h>
+
+
+int
+main(int argc, char **argv)
+{
+	mpd_context_t ctx;
+	mpd_t *a, *b;
+	mpd_t *result;
+	char *rstring;
+	char status_str[MPD_MAX_FLAG_STRING];
+	clock_t start_clock, end_clock;
+
+	if (argc != 3) {
+		fprintf(stderr, "pow: usage: ./pow x y\n");
+		exit(1);
+	}
+
+	mpd_init(&ctx, 38);
+	ctx.traps = 0;
+
+	result = mpd_new(&ctx);
+	a = mpd_new(&ctx);
+	b = mpd_new(&ctx);
+	mpd_set_string(a, argv[1], &ctx);
+	mpd_set_string(b, argv[2], &ctx);
+
+	start_clock = clock();
+	mpd_pow(result, a, b, &ctx);
+	end_clock = clock();
+	fprintf(stderr, "time: %f\n\n",
+	           (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
+
+	rstring = mpd_to_sci(result, 1);
+	mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status);
+	printf("%s  %s\n", rstring, status_str);
+
+	mpd_del(a);
+	mpd_del(b);
+	mpd_del(result);
+	mpd_free(rstring);
+
+	return 0;
+}
+
+
diff --git a/Modules/_decimal/libmpdec/examples/powmod.c b/Modules/_decimal/libmpdec/examples/powmod.c
new file mode 100644
index 0000000000000..b422fdbbb955d
--- /dev/null
+++ b/Modules/_decimal/libmpdec/examples/powmod.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <mpdecimal.h>
+
+
+int
+main(int argc, char **argv)
+{
+	mpd_context_t ctx;
+	mpd_t *a, *b, *c;
+	mpd_t *result;
+	char *rstring;
+	char status_str[MPD_MAX_FLAG_STRING];
+	clock_t start_clock, end_clock;
+
+	if (argc != 4) {
+		fprintf(stderr, "powmod: usage: ./powmod x y z\n");
+		exit(1);
+	}
+
+	mpd_init(&ctx, 38);
+	ctx.traps = 0;
+
+	result = mpd_new(&ctx);
+	a = mpd_new(&ctx);
+	b = mpd_new(&ctx);
+	c = mpd_new(&ctx);
+	mpd_set_string(a, argv[1], &ctx);
+	mpd_set_string(b, argv[2], &ctx);
+	mpd_set_string(c, argv[3], &ctx);
+
+	start_clock = clock();
+	mpd_powmod(result, a, b, c, &ctx);
+	end_clock = clock();
+	fprintf(stderr, "time: %f\n\n",
+	           (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
+
+	rstring = mpd_to_sci(result, 1);
+	mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status);
+	printf("%s  %s\n", rstring, status_str);
+
+	mpd_del(a);
+	mpd_del(b);
+	mpd_del(c);
+	mpd_del(result);
+	mpd_free(rstring);
+
+	return 0;
+}
+
+
diff --git a/Modules/_decimal/libmpdec/examples/shift.c b/Modules/_decimal/libmpdec/examples/shift.c
new file mode 100644
index 0000000000000..6d54e108ca87f
--- /dev/null
+++ b/Modules/_decimal/libmpdec/examples/shift.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <mpdecimal.h>
+
+
+int
+main(int argc, char **argv)
+{
+	mpd_context_t ctx;
+	mpd_t *a, *b;
+	mpd_t *result;
+	char *rstring;
+	char status_str[MPD_MAX_FLAG_STRING];
+	clock_t start_clock, end_clock;
+
+	if (argc != 3) {
+		fprintf(stderr, "shift: usage: ./shift x y\n");
+		exit(1);
+	}
+
+	mpd_init(&ctx, 38);
+	ctx.traps = 0;
+
+	result = mpd_new(&ctx);
+	a = mpd_new(&ctx);
+	b = mpd_new(&ctx);
+	mpd_set_string(a, argv[1], &ctx);
+	mpd_set_string(b, argv[2], &ctx);
+
+	start_clock = clock();
+	mpd_shift(result, a, b, &ctx);
+	end_clock = clock();
+	fprintf(stderr, "time: %f\n\n",
+	           (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
+
+	rstring = mpd_to_sci(result, 1);
+	mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status);
+	printf("%s  %s\n", rstring, status_str);
+
+	mpd_del(a);
+	mpd_del(b);
+	mpd_del(result);
+	mpd_free(rstring);
+
+	return 0;
+}
+
+
diff --git a/Modules/_decimal/libmpdec/vccompat.h b/Modules/_decimal/libmpdec/examples/sqrt.c
similarity index 62%
rename from Modules/_decimal/libmpdec/vccompat.h
rename to Modules/_decimal/libmpdec/examples/sqrt.c
index e2e1c42cc0250..d8272789b18c2 100644
--- a/Modules/_decimal/libmpdec/vccompat.h
+++ b/Modules/_decimal/libmpdec/examples/sqrt.c
@@ -26,31 +26,49 @@
  */
 
 
-#ifndef LIBMPDEC_VCCOMPAT_H_
-#define LIBMPDEC_VCCOMPAT_H_
-
-
-/* Visual C fixes: no snprintf ... */
-#ifdef _MSC_VER
-  #ifndef __cplusplus
-    #undef inline
-    #define inline __inline
-  #endif
-  #undef random
-  #define random rand
-  #undef srandom
-  #define srandom srand
-  #undef snprintf
-  #define snprintf sprintf_s
-  #define HAVE_SNPRINTF
-  #undef strncasecmp
-  #define strncasecmp _strnicmp
-  #undef strcasecmp
-  #define strcasecmp _stricmp
-  #undef strtoll
-  #define strtoll _strtoi64
-  #define strdup _strdup
-#endif
-
-
-#endif /* LIBMPDEC_VCCOMPAT_H_ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <mpdecimal.h>
+
+
+int
+main(int argc, char **argv)
+{
+	mpd_context_t ctx;
+	mpd_t *a;
+	mpd_t *result;
+	char *rstring;
+	char status_str[MPD_MAX_FLAG_STRING];
+	clock_t start_clock, end_clock;
+
+	if (argc != 2) {
+		fprintf(stderr, "sqrt: usage: ./sqrt x\n");
+		exit(1);
+	}
+
+	mpd_init(&ctx, 38);
+	ctx.traps = 0;
+
+	result = mpd_new(&ctx);
+	a = mpd_new(&ctx);
+	mpd_set_string(a, argv[1], &ctx);
+
+	start_clock = clock();
+	mpd_sqrt(result, a, &ctx);
+	end_clock = clock();
+	fprintf(stderr, "time: %f\n\n",
+	           (double)(end_clock-start_clock)/(double)CLOCKS_PER_SEC);
+
+	rstring = mpd_to_sci(result, 1);
+	mpd_snprint_flags(status_str, MPD_MAX_FLAG_STRING, ctx.status);
+	printf("%s  %s\n", rstring, status_str);
+
+	mpd_del(a);
+	mpd_del(result);
+	mpd_free(rstring);
+
+	return 0;
+}
+
+
diff --git a/Modules/_decimal/libmpdec/io.c b/Modules/_decimal/libmpdec/io.c
index 9513a68e3782d..e7bd6aee17005 100644
--- a/Modules/_decimal/libmpdec/io.c
+++ b/Modules/_decimal/libmpdec/io.c
@@ -37,17 +37,17 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "typearith.h"
 #include "io.h"
+#include "typearith.h"
 
 
 /* This file contains functions for decimal <-> string conversions, including
    PEP-3101 formatting for numeric types. */
 
 
-/* Disable warning that is part of -Wextra since gcc 7.0. */
 #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && __GNUC__ >= 7
   #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+  #pragma GCC diagnostic ignored "-Wmisleading-indentation"
 #endif
 
 
@@ -155,13 +155,13 @@ scan_dpoint_exp(const char *s, const char **dpoint, const char **exp,
                 s++;
             break;
         default:
-            if (!isdigit((uchar)*s))
+            if (!isdigit((unsigned char)*s))
                 return NULL;
             if (coeff == NULL && *exp == NULL) {
                 if (*s == '0') {
-                    if (!isdigit((uchar)*(s+1)))
+                    if (!isdigit((unsigned char)*(s+1)))
                         if (!(*(s+1) == '.' &&
-                              isdigit((uchar)*(s+2))))
+                              isdigit((unsigned char)*(s+2))))
                             coeff = s;
                 }
                 else {
@@ -187,7 +187,7 @@ scan_payload(const char *s, const char **end)
         s++;
     coeff = s;
 
-    while (isdigit((uchar)*s))
+    while (isdigit((unsigned char)*s))
         s++;
     *end = s;
 
@@ -689,8 +689,8 @@ mpd_to_eng_size(char **res, const mpd_t *dec, int fmt)
 static int
 _mpd_copy_utf8(char dest[5], const char *s)
 {
-    const uchar *cp = (const uchar *)s;
-    uchar lb, ub;
+    const unsigned char *cp = (const unsigned char *)s;
+    unsigned char lb, ub;
     int count, i;
 
 
@@ -843,7 +843,7 @@ mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps)
     }
 
     /* minimum width */
-    if (isdigit((uchar)*cp)) {
+    if (isdigit((unsigned char)*cp)) {
         if (*cp == '0') {
             return 0;
         }
@@ -865,7 +865,7 @@ mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps)
     /* fraction digits or significant digits */
     if (*cp == '.') {
         cp++;
-        if (!isdigit((uchar)*cp)) {
+        if (!isdigit((unsigned char)*cp)) {
             return 0;
         }
         errno = 0;
@@ -1105,9 +1105,9 @@ _mpd_apply_lconv(mpd_mbstr_t *result, const mpd_spec_t *spec, uint32_t *status)
         sign = dp++;
     }
     /* integer part */
-    assert(isdigit((uchar)*dp));
+    assert(isdigit((unsigned char)*dp));
     intpart = dp++;
-    while (isdigit((uchar)*dp)) {
+    while (isdigit((unsigned char)*dp)) {
         dp++;
     }
     n_int = (mpd_ssize_t)(dp-intpart);
@@ -1262,8 +1262,8 @@ mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec,
         return NULL;
     }
 
-    if (isupper((uchar)type)) {
-        type = (char)tolower((uchar)type);
+    if (isupper((unsigned char)type)) {
+        type = (char)tolower((unsigned char)type);
         flags |= MPD_FMT_UPPER;
     }
     if (spec->sign == ' ') {
diff --git a/Modules/_decimal/libmpdec/mpalloc.c b/Modules/_decimal/libmpdec/mpalloc.c
index eb5ee7a807b33..5871d5c0f5351 100644
--- a/Modules/_decimal/libmpdec/mpalloc.c
+++ b/Modules/_decimal/libmpdec/mpalloc.c
@@ -61,13 +61,6 @@ mpd_callocfunc_em(size_t nmemb, size_t size)
     size_t req;
     mpd_size_t overflow;
 
-#if MPD_SIZE_MAX < SIZE_MAX
-    /* full_coverage test only */
-    if (nmemb > MPD_SIZE_MAX || size > MPD_SIZE_MAX) {
-        return NULL;
-    }
-#endif
-
     req = mul_size_t_overflow((mpd_size_t)nmemb, (mpd_size_t)size,
                               &overflow);
     if (overflow) {
diff --git a/Modules/_decimal/libmpdec/mpalloc.h b/Modules/_decimal/libmpdec/mpalloc.h
index 186808457b25c..2265004421824 100644
--- a/Modules/_decimal/libmpdec/mpalloc.h
+++ b/Modules/_decimal/libmpdec/mpalloc.h
@@ -39,12 +39,12 @@
 MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
 
 
-int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status);
-int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status);
-int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status);
+int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t nwords, uint32_t *status);
+int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t nwords, uint32_t *status);
+int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t nwords, uint32_t *status);
 
-int mpd_switch_to_dyn_cxx(mpd_t *result, mpd_ssize_t size);
-int mpd_realloc_dyn_cxx(mpd_t *result, mpd_ssize_t size);
+int mpd_switch_to_dyn_cxx(mpd_t *result, mpd_ssize_t nwords);
+int mpd_realloc_dyn_cxx(mpd_t *result, mpd_ssize_t nwords);
 
 
 MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c
index f0e4d7f343a43..f1626df46ed46 100644
--- a/Modules/_decimal/libmpdec/mpdecimal.c
+++ b/Modules/_decimal/libmpdec/mpdecimal.c
@@ -64,7 +64,7 @@
 
 #if defined(_MSC_VER)
   #define ALWAYS_INLINE __forceinline
-#elif defined(__IBMC__) || defined(LEGACY_COMPILER)
+#elif defined (__IBMC__) || defined(LEGACY_COMPILER)
   #define ALWAYS_INLINE
   #undef inline
   #define inline
@@ -4843,7 +4843,7 @@ _mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
          uint32_t *status)
 {
     mpd_context_t varcontext, maxcontext;
-    mpd_t *z = (mpd_t *) result;
+    mpd_t *z = result;
     MPD_NEW_STATIC(v,0,0,0,0);
     MPD_NEW_STATIC(vtmp,0,0,0,0);
     MPD_NEW_STATIC(tmp,0,0,0,0);
@@ -6368,7 +6368,7 @@ _mpd_qpow_int(mpd_t *result, const mpd_t *base, const mpd_t *exp,
     mpd_context_t workctx;
     MPD_NEW_STATIC(tbase,0,0,0,0);
     MPD_NEW_STATIC(texp,0,0,0,0);
-    mpd_ssize_t n;
+    mpd_uint_t n;
 
 
     mpd_workcontext(&workctx, ctx);
@@ -8090,7 +8090,6 @@ mpd_sizeinbase(const mpd_t *a, uint32_t base)
     }
 
     digits = a->digits+a->exp;
-    assert(digits > 0);
 
 #ifdef CONFIG_64
     /* ceil(2711437152599294 / log10(2)) + 4 == 2**53 */
diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h
index 9c9f1ca443402..24c280b00ebcd 100644
--- a/Modules/_decimal/libmpdec/mpdecimal.h
+++ b/Modules/_decimal/libmpdec/mpdecimal.h
@@ -40,6 +40,7 @@
   #include <cstdint>
   #include <cstdio>
   #include <cstdlib>
+  #define MPD_UINT8_C(x) (static_cast<uint8_t>(x))
 extern "C" {
 #else
   #include <inttypes.h>
@@ -47,6 +48,7 @@ extern "C" {
   #include <stdint.h>
   #include <stdio.h>
   #include <stdlib.h>
+  #define MPD_UINT8_C(x) ((uint8_t)x)
 #endif
 
 
@@ -62,7 +64,6 @@ extern "C" {
 #endif
 
 #if defined(_MSC_VER)
-  #include "vccompat.h"
   #define EXTINLINE extern inline
 #else
   #define EXTINLINE
@@ -74,25 +75,15 @@ extern "C" {
 MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
 
 
-#if !defined(LEGACY_COMPILER)
-  #if !defined(UINT64_MAX)
-    /* The following #error is just a warning. If the compiler indeed does
-     * not have uint64_t, it is perfectly safe to comment out the #error. */
-    #error "Warning: Compiler without uint64_t. Comment out this line."
-    #define LEGACY_COMPILER
-  #endif
-#endif
-
-
 /******************************************************************************/
 /*                                  Version                                   */
 /******************************************************************************/
 
 #define MPD_MAJOR_VERSION 2
 #define MPD_MINOR_VERSION 5
-#define MPD_MICRO_VERSION 0
+#define MPD_MICRO_VERSION 1
 
-#define MPD_VERSION "2.5.0"
+#define MPD_VERSION "2.5.1"
 
 #define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \
                          (MPD_MINOR_VERSION << 16) | \
@@ -162,6 +153,7 @@ typedef int64_t mpd_ssize_t;
 #define MPD_EXP_INF 2000000000000000001LL
 #define MPD_EXP_CLAMP (-4000000000000000001LL)
 #define MPD_MAXIMPORT 105263157894736842L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */
+#define MPD_IEEE_CONTEXT_MAX_BITS 512     /* 16*(log2(MPD_MAX_EMAX / 3)-3) */
 
 /* conversion specifiers */
 #define PRI_mpd_uint_t PRIu64
@@ -203,9 +195,10 @@ typedef int32_t mpd_ssize_t;
 #define MPD_MAX_EMAX 425000000L        /* ELIMIT-1 */
 #define MPD_MIN_EMIN (-425000000L)     /* -EMAX */
 #define MPD_MIN_ETINY (MPD_MIN_EMIN-(MPD_MAX_PREC-1))
-#define MPD_EXP_INF 1000000001L      /* allows for emax=999999999 in the tests */
-#define MPD_EXP_CLAMP (-2000000001L) /* allows for emin=-999999999 in the tests */
-#define MPD_MAXIMPORT 94444445L      /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */
+#define MPD_EXP_INF 1000000001L       /* allows for emax=999999999 in the tests */
+#define MPD_EXP_CLAMP (-2000000001L)  /* allows for emin=-999999999 in the tests */
+#define MPD_MAXIMPORT 94444445L       /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */
+#define MPD_IEEE_CONTEXT_MAX_BITS 256 /* 16*(log2(MPD_MAX_EMAX / 3)-3) */
 
 /* conversion specifiers */
 #define PRI_mpd_uint_t PRIu32
@@ -242,8 +235,8 @@ enum {
 
 enum { MPD_CLAMP_DEFAULT, MPD_CLAMP_IEEE_754, MPD_CLAMP_GUARD };
 
-extern const char *mpd_round_string[MPD_ROUND_GUARD];
-extern const char *mpd_clamp_string[MPD_CLAMP_GUARD];
+extern const char * const mpd_round_string[MPD_ROUND_GUARD];
+extern const char * const mpd_clamp_string[MPD_CLAMP_GUARD];
 
 
 typedef struct mpd_context_t {
@@ -300,7 +293,6 @@ typedef struct mpd_context_t {
 #define MPD_Insufficient_storage MPD_Malloc_error
 
 /* IEEE 754 interchange format contexts */
-#define MPD_IEEE_CONTEXT_MAX_BITS 512 /* 16*(log2(MPD_MAX_EMAX / 3)-3) */
 #define MPD_DECIMAL32 32
 #define MPD_DECIMAL64 64
 #define MPD_DECIMAL128 128
@@ -345,16 +337,16 @@ void mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags);
 /******************************************************************************/
 
 /* mpd_t flags */
-#define MPD_POS                 ((uint8_t)0)
-#define MPD_NEG                 ((uint8_t)1)
-#define MPD_INF                 ((uint8_t)2)
-#define MPD_NAN                 ((uint8_t)4)
-#define MPD_SNAN                ((uint8_t)8)
+#define MPD_POS                 MPD_UINT8_C(0)
+#define MPD_NEG                 MPD_UINT8_C(1)
+#define MPD_INF                 MPD_UINT8_C(2)
+#define MPD_NAN                 MPD_UINT8_C(4)
+#define MPD_SNAN                MPD_UINT8_C(8)
 #define MPD_SPECIAL (MPD_INF|MPD_NAN|MPD_SNAN)
-#define MPD_STATIC              ((uint8_t)16)
-#define MPD_STATIC_DATA         ((uint8_t)32)
-#define MPD_SHARED_DATA         ((uint8_t)64)
-#define MPD_CONST_DATA          ((uint8_t)128)
+#define MPD_STATIC              MPD_UINT8_C(16)
+#define MPD_STATIC_DATA         MPD_UINT8_C(32)
+#define MPD_SHARED_DATA         MPD_UINT8_C(64)
+#define MPD_CONST_DATA          MPD_UINT8_C(128)
 #define MPD_DATAFLAGS (MPD_STATIC_DATA|MPD_SHARED_DATA|MPD_CONST_DATA)
 
 /* mpd_t */
@@ -368,9 +360,6 @@ typedef struct mpd_t {
 } mpd_t;
 
 
-typedef unsigned char uchar;
-
-
 /******************************************************************************/
 /*                                    Triple                                  */
 /******************************************************************************/
@@ -442,7 +431,7 @@ void mpd_qset_string_exact(mpd_t *dec, const char *s, uint32_t *status);
 /* set to NaN with error flags */
 void mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status);
 /* set a special with sign and type */
-void mpd_setspecial(mpd_t *dec, uint8_t sign, uint8_t type);
+void mpd_setspecial(mpd_t *result, uint8_t sign, uint8_t type);
 /* set coefficient to zero or all nines */
 void mpd_zerocoeff(mpd_t *result);
 void mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status);
@@ -835,16 +824,16 @@ void *mpd_sh_alloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size);
 
 mpd_t *mpd_qnew(void);
 mpd_t *mpd_new(mpd_context_t *ctx);
-mpd_t *mpd_qnew_size(mpd_ssize_t size);
+mpd_t *mpd_qnew_size(mpd_ssize_t nwords);
 EXTINLINE void mpd_del(mpd_t *dec);
 
 EXTINLINE void mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len);
-EXTINLINE int mpd_qresize(mpd_t *result, mpd_ssize_t size, uint32_t *status);
-EXTINLINE int mpd_qresize_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status);
+EXTINLINE int mpd_qresize(mpd_t *result, mpd_ssize_t nwords, uint32_t *status);
+EXTINLINE int mpd_qresize_zero(mpd_t *result, mpd_ssize_t nwords, uint32_t *status);
 EXTINLINE void mpd_minalloc(mpd_t *result);
 
-int mpd_resize(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx);
-int mpd_resize_zero(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx);
+int mpd_resize(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx);
+int mpd_resize_zero(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx);
 
 
 MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
diff --git a/Modules/_decimal/libmpdec/mpsignal.c b/Modules/_decimal/libmpdec/mpsignal.c
new file mode 100644
index 0000000000000..fc2af48f4f379
--- /dev/null
+++ b/Modules/_decimal/libmpdec/mpsignal.c
@@ -0,0 +1,967 @@
+/*
+ * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include "mpdecimal.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+
+/* Signaling wrappers for the quiet functions in mpdecimal.c. */
+
+
+char *
+mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx)
+{
+    char *ret;
+    uint32_t status = 0;
+    ret = mpd_qformat(dec, fmt, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+    return ret;
+}
+
+void
+mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen,
+               uint8_t srcsign, uint32_t base, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qimport_u16(result, srcdata, srclen, srcsign, base, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen,
+               uint8_t srcsign, uint32_t base, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qimport_u32(result, srcdata, srclen, srcsign, base, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+size_t
+mpd_export_u16(uint16_t **rdata, size_t rlen, uint32_t base, const mpd_t *src,
+               mpd_context_t *ctx)
+{
+    size_t n;
+    uint32_t status = 0;
+    n = mpd_qexport_u16(rdata, rlen, base, src, &status);
+    mpd_addstatus_raise(ctx, status);
+    return n;
+}
+
+size_t
+mpd_export_u32(uint32_t **rdata, size_t rlen, uint32_t base, const mpd_t *src,
+               mpd_context_t *ctx)
+{
+    size_t n;
+    uint32_t status = 0;
+    n = mpd_qexport_u32(rdata, rlen, base, src, &status);
+    mpd_addstatus_raise(ctx, status);
+    return n;
+}
+
+void
+mpd_finalize(mpd_t *result, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qfinalize(result, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+int
+mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    if (mpd_qcheck_nan(result, a, ctx, &status)) {
+        mpd_addstatus_raise(ctx, status);
+        return 1;
+    }
+    return 0;
+}
+
+int
+mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    if (mpd_qcheck_nans(result, a, b, ctx, &status)) {
+        mpd_addstatus_raise(ctx, status);
+        return 1;
+    }
+    return 0;
+}
+
+void
+mpd_set_string(mpd_t *result, const char *s, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qset_string(result, s, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_maxcoeff(mpd_t *result, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmaxcoeff(result, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+/* set static mpd from signed integer */
+void
+mpd_sset_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsset_ssize(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sset_i32(mpd_t *result, int32_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsset_i32(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_sset_i64(mpd_t *result, int64_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsset_i64(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+/* set static mpd from unsigned integer */
+void
+mpd_sset_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsset_uint(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sset_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsset_u32(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_sset_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsset_u64(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+/* set mpd from signed integer */
+void
+mpd_set_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qset_ssize(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_set_i32(mpd_t *result, int32_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qset_i32(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifndef LEGACY_COMPILER
+void
+mpd_set_i64(mpd_t *result, int64_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qset_i64(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+/* set mpd from unsigned integer */
+void
+mpd_set_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qset_uint(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_set_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qset_u32(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifndef LEGACY_COMPILER
+void
+mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qset_u64(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+/* convert mpd to signed integer */
+mpd_ssize_t
+mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_ssize_t ret;
+
+    ret = mpd_qget_ssize(a, &status);
+    mpd_addstatus_raise(ctx, status);
+    return ret;
+}
+
+int32_t
+mpd_get_i32(const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    int32_t ret;
+
+    ret = mpd_qget_i32(a, &status);
+    mpd_addstatus_raise(ctx, status);
+    return ret;
+}
+
+#ifndef LEGACY_COMPILER
+int64_t
+mpd_get_i64(const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    int64_t ret;
+
+    ret = mpd_qget_i64(a, &status);
+    mpd_addstatus_raise(ctx, status);
+    return ret;
+}
+#endif
+
+mpd_uint_t
+mpd_get_uint(const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_uint_t ret;
+
+    ret = mpd_qget_uint(a, &status);
+    mpd_addstatus_raise(ctx, status);
+    return ret;
+}
+
+mpd_uint_t
+mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_uint_t ret;
+
+    ret = mpd_qabs_uint(a, &status);
+    mpd_addstatus_raise(ctx, status);
+    return ret;
+}
+
+uint32_t
+mpd_get_u32(const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    uint32_t ret;
+
+    ret = mpd_qget_u32(a, &status);
+    mpd_addstatus_raise(ctx, status);
+    return ret;
+}
+
+#ifndef LEGACY_COMPILER
+uint64_t
+mpd_get_u64(const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    uint64_t ret;
+
+    ret = mpd_qget_u64(a, &status);
+    mpd_addstatus_raise(ctx, status);
+    return ret;
+}
+#endif
+
+void
+mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qand(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    if (!mpd_qcopy(result, a, &status)) {
+        mpd_addstatus_raise(ctx, status);
+    }
+}
+
+void
+mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    mpd_copy(result, a, ctx);
+}
+
+void
+mpd_copy_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    if (!mpd_qcopy_abs(result, a, &status)) {
+        mpd_addstatus_raise(ctx, status);
+    }
+}
+
+void
+mpd_copy_negate(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    if (!mpd_qcopy_negate(result, a, &status)) {
+        mpd_addstatus_raise(ctx, status);
+    }
+}
+
+void
+mpd_copy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    if (!mpd_qcopy_sign(result, a, b, &status)) {
+        mpd_addstatus_raise(ctx, status);
+    }
+}
+
+void
+mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qinvert(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_logb(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qlogb(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qor(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qrotate(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_scaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qscaleb(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qshiftl(result, a, n, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+mpd_uint_t
+mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_uint_t rnd;
+
+    rnd = mpd_qshiftr(result, a, n, &status);
+    mpd_addstatus_raise(ctx, status);
+    return rnd;
+}
+
+void
+mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qshiftn(result, a, n, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qshift(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qxor(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qabs(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+int
+mpd_cmp(const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    int c;
+    c = mpd_qcmp(a, b, &status);
+    mpd_addstatus_raise(ctx, status);
+    return c;
+}
+
+int
+mpd_compare(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    int c;
+    c = mpd_qcompare(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+    return c;
+}
+
+int
+mpd_compare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    int c;
+    c = mpd_qcompare_signal(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+    return c;
+}
+
+void
+mpd_add(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qadd(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sub(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsub(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_add_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qadd_ssize(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_add_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qadd_i32(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifndef LEGACY_COMPILER
+void
+mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qadd_i64(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_add_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qadd_uint(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_add_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qadd_u32(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifndef LEGACY_COMPILER
+void
+mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qadd_u64(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_sub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsub_ssize(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sub_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsub_i32(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifndef LEGACY_COMPILER
+void
+mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsub_i64(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_sub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsub_uint(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sub_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsub_u32(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifndef LEGACY_COMPILER
+void
+mpd_sub_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsub_u64(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_div(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qdiv(q, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_div_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qdiv_ssize(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_div_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qdiv_i32(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifndef LEGACY_COMPILER
+void
+mpd_div_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qdiv_i64(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_div_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qdiv_uint(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_div_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qdiv_u32(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifndef LEGACY_COMPILER
+void
+mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qdiv_u64(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qdivmod(q, r, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_divint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qdivint(q, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_exp(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qexp(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_fma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c,
+        mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qfma(result, a, b, c, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_ln(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qln(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_log10(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qlog10(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_max(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmax(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_max_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmax_mag(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_min(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmin(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_min_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmin_mag(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qminus(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_mul(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmul(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_mul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmul_ssize(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_mul_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmul_i32(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifndef LEGACY_COMPILER
+void
+mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmul_i64(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_mul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmul_uint(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_mul_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmul_u32(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+#ifndef LEGACY_COMPILER
+void
+mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qmul_u64(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_next_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qnext_minus(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_next_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qnext_plus(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_next_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qnext_toward(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qplus(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_pow(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qpow(result, base, exp, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_powmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod,
+           mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qpowmod(result, base, exp, mod, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_quantize(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qquantize(result, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_rescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qrescale(result, a, exp, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_reduce(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qreduce(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_rem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qrem(r, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_rem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qrem_near(r, a, b, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_round_to_intx(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qround_to_intx(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_round_to_int(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qround_to_int(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_trunc(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qtrunc(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_floor(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qfloor(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qceil(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qsqrt(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+    uint32_t status = 0;
+    mpd_qinvroot(result, a, ctx, &status);
+    mpd_addstatus_raise(ctx, status);
+}
diff --git a/Modules/_decimal/libmpdec/typearith.h b/Modules/_decimal/libmpdec/typearith.h
index 47961788d7641..dd3776453d098 100644
--- a/Modules/_decimal/libmpdec/typearith.h
+++ b/Modules/_decimal/libmpdec/typearith.h
@@ -638,10 +638,10 @@ add_size_t_overflow(mpd_size_t a, mpd_size_t b, mpd_size_t *overflow)
 static inline mpd_size_t
 mul_size_t_overflow(mpd_size_t a, mpd_size_t b, mpd_size_t *overflow)
 {
-    mpd_uint_t lo;
+    mpd_uint_t hi, lo;
 
-    _mpd_mul_words((mpd_uint_t *)overflow, &lo, (mpd_uint_t)a,
-                   (mpd_uint_t)b);
+    _mpd_mul_words(&hi, &lo, (mpd_uint_t)a, (mpd_uint_t)b);
+    *overflow = (mpd_size_t)hi;
     return lo;
 }
 
diff --git a/setup.py b/setup.py
index a7d00841d0559..e3fbd78bc08b8 100644
--- a/setup.py
+++ b/setup.py
@@ -2290,7 +2290,7 @@ def detect_decimal(self):
         undef_macros = []
         if '--with-system-libmpdec' in sysconfig.get_config_var("CONFIG_ARGS"):
             include_dirs = []
-            libraries = [':libmpdec.so.2']
+            libraries = ['mpdec']
             sources = ['_decimal/_decimal.c']
             depends = ['_decimal/docstrings.h']
         else:



More information about the Python-checkins mailing list