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@bytereef.org>
This commit is contained in:
Antoine Pitrou 2021-03-30 18:11:06 +02:00 committed by GitHub
parent a7ff6df60c
commit 73b20ae2fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 1966 additions and 113 deletions

View file

@ -0,0 +1,2 @@
Finish updating the vendored libmpdec to version 2.5.1. Patch by Stefan
Krah.

View file

@ -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) {

View file

@ -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.

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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"
};

View file

@ -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;
}

View file

@ -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]);
s = w[1] + (v[1] + carry);
carry = (s < w[1]);
w[1] = s;
w[1] = w[1] + v[1];
if (w[1] < v[1]) w[2]++;
w[2] = w[2] + (v[2] + carry);
w[1] = w[1] + carry;
if (w[1] < carry) w[2]++;
w[2] += v[2];
}
/* Divide 3 words in u by v, store result in w, return remainder. */

View file

@ -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 */

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -26,31 +26,49 @@
*/
#ifndef LIBMPDEC_VCCOMPAT_H_
#define LIBMPDEC_VCCOMPAT_H_
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mpdecimal.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
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;
}
#endif /* LIBMPDEC_VCCOMPAT_H_ */

View file

@ -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 == ' ') {

View file

@ -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) {

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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: