--- /n/sources/plan9/sys/include/mp.h Thu Jun 27 01:38:28 2024 +++ /sys/include/mp.h Thu Jun 27 02:02:05 2024 @@ -81,6 +81,9 @@ /* return neg, 0, pos as b1-b2 is neg, 0, pos */ int mpcmp(mpint *b1, mpint *b2); +/* res = s != 0 ? b1 : b2 */ +void mpsel(int s, mpint *b1, mpint *b2, mpint *res); + /* extended gcd return d, x, and y, s.t. d = gcd(a,b) and ax+by = d */ void mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x, mpint *y); --- /n/sources/plan9/sys/include/ape/mp.h Thu Jun 27 01:38:28 2024 +++ /sys/include/ape/mp.h Thu Jun 27 02:04:07 2024 @@ -90,6 +90,9 @@ /* return neg, 0, pos as b1-b2 is neg, 0, pos */ int mpcmp(mpint *b1, mpint *b2); +/* res = s != 0 ? b1 : b2 */ +void mpsel(int s, mpint *b1, mpint *b2, mpint *res); + /* extended gcd return d, x, and y, s.t. d = gcd(a,b) and ax+by = d */ void mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x, mpint *y); --- /n/sources/plan9/sys/man/2/mp Thu Jun 27 01:38:28 2024 +++ /sys/man/2/mp Thu Jun 27 02:02:06 2024 @@ -1,6 +1,6 @@ .TH MP 2 .SH NAME -mpsetminbits, mpnew, mpfree, mpbits, mpnorm, mpcopy, mpassign, mprand, mpnrand, strtomp, mpfmt,mptoa, betomp, mptobe, mptober, letomp, mptole, mptolel, mptoui, uitomp, mptoi, itomp, uvtomp, mptouv, vtomp, mptov, mpdigdiv, mpadd, mpsub, mpleft, mpright, mpmul, mpexp, mpmod, mpdiv, mpcmp, mpextendedgcd, mpinvert, mpsignif, mplowbits0, mpvecdigmuladd, mpvecdigmulsub, mpvecadd, mpvecsub, mpveccmp, mpvecmul, mpmagcmp, mpmagadd, mpmagsub, crtpre, crtin, crtout, crtprefree, crtresfree \- extended precision arithmetic +mpsetminbits, mpnew, mpfree, mpbits, mpnorm, mpcopy, mpassign, mprand, mpnrand, strtomp, mpfmt,mptoa, betomp, mptobe, mptober, letomp, mptole, mptolel, mptoui, uitomp, mptoi, itomp, uvtomp, mptouv, vtomp, mptov, mpdigdiv, mpadd, mpsub, mpleft, mpright, mpmul, mpexp, mpmod, mpdiv, mpcmp¸ mpsel, mpextendedgcd, mpinvert, mpsignif, mplowbits0, mpvecdigmuladd, mpvecdigmulsub, mpvecadd, mpvecsub, mpveccmp, mpvecmul, mpmagcmp, mpmagadd, mpmagsub, crtpre, crtin, crtout, crtprefree, crtresfree \- extended precision arithmetic .SH SYNOPSIS .B #include .br @@ -127,6 +127,9 @@ int mpmagcmp(mpint *b1, mpint *b2) .PP .B +void mpsel(int s, mpint *b1, mpint *b2, mpint *res) +.PP +.B void mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x, .br .B @@ -510,6 +513,18 @@ the same as .I mpcmp but ignores the sign and just compares magnitudes. +.TP +.I mpsel +assigns +.I b1 +to +.I res +when +.I s +is not zero, otherwise +.I b2 +is assigned to +.IR res . .PD .PP .I Mpextendedgcd diff -Nru /n/sources/plan9/sys/src/ape/lib/mp/port/mkfile /sys/src/ape/lib/mp/port/mkfile --- /n/sources/plan9/sys/src/ape/lib/mp/port/mkfile Thu Jun 27 00:35:51 2024 +++ /sys/src/ape/lib/mp/port/mkfile Thu Jun 27 02:04:34 2024 @@ -16,6 +16,7 @@ mpadd\ mpsub\ mpcmp\ + mpsel\ mpfactorial\ mpmul\ mpleft\ diff -Nru /n/sources/plan9/sys/src/libmp/port/mkfile /sys/src/libmp/port/mkfile --- /n/sources/plan9/sys/src/libmp/port/mkfile Thu Jun 27 00:16:50 2024 +++ /sys/src/libmp/port/mkfile Thu Jun 27 02:02:06 2024 @@ -14,6 +14,7 @@ mpadd\ mpsub\ mpcmp\ + mpsel\ mpfactorial\ mpmul\ mpleft\ diff -Nru /n/sources/plan9/sys/src/libmp/port/mpsel.c /sys/src/libmp/port/mpsel.c --- /n/sources/plan9/sys/src/libmp/port/mpsel.c Wed Dec 31 19:00:00 1969 +++ /sys/src/libmp/port/mpsel.c Thu Jun 27 02:02:09 2024 @@ -0,0 +1,42 @@ +#include "os.h" +#include +#include "dat.h" + +// res = s != 0 ? b1 : b2 +void +mpsel(int s, mpint *b1, mpint *b2, mpint *res) +{ + mpdigit d; + int n, m, i; + + res->flags |= (b1->flags | b2->flags) & MPtimesafe; + if((res->flags & MPtimesafe) == 0){ + mpassign(s ? b1 : b2, res); + return; + } + res->flags &= ~MPnorm; + + n = b1->top; + m = b2->top; + mpbits(res, Dbits*(n >= m ? n : m)); + res->top = n >= m ? n : m; + + s = (-s^s|s)>>(sizeof(s)*8-1); + res->sign = (b1->sign & s) | (b2->sign & ~s); + + d = -((mpdigit)s & 1); + + i = 0; + while(i < n && i < m){ + res->p[i] = (b1->p[i] & d) | (b2->p[i] & ~d); + i++; + } + while(i < n){ + res->p[i] = b1->p[i] & d; + i++; + } + while(i < m){ + res->p[i] = b2->p[i] & ~d; + i++; + } +}