mp: add mptod and dtomp
This commit is contained in:
parent
bf555abcc3
commit
b9a08958e2
3 changed files with 105 additions and 3 deletions
24
sys/man/2/mp
24
sys/man/2/mp
|
@ -1,6 +1,6 @@
|
||||||
.TH MP 2
|
.TH MP 2
|
||||||
.SH NAME
|
.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, mpmodadd, mpmodsub, mpmodmul, mpdiv, mpcmp, mpsel, 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, mptod, dtomp, mpdigdiv, mpadd, mpsub, mpleft, mpright, mpmul, mpexp, mpmod, mpmodadd, mpmodsub, mpmodmul, 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
|
.SH SYNOPSIS
|
||||||
.B #include <u.h>
|
.B #include <u.h>
|
||||||
.br
|
.br
|
||||||
|
@ -88,6 +88,12 @@ mpint* uvtomp(uvlong, mpint*)
|
||||||
uvlong mptouv(mpint*)
|
uvlong mptouv(mpint*)
|
||||||
.PP
|
.PP
|
||||||
.B
|
.B
|
||||||
|
mpint* dtomp(double, mpint*)
|
||||||
|
.PP
|
||||||
|
.B
|
||||||
|
double mptod(mpint*)
|
||||||
|
.PP
|
||||||
|
.B
|
||||||
void mpadd(mpint *b1, mpint *b2, mpint *sum)
|
void mpadd(mpint *b1, mpint *b2, mpint *sum)
|
||||||
.PP
|
.PP
|
||||||
.B
|
.B
|
||||||
|
@ -271,8 +277,9 @@ This includes
|
||||||
.IR strtomp ,
|
.IR strtomp ,
|
||||||
.IR itomp ,
|
.IR itomp ,
|
||||||
.IR uitomp ,
|
.IR uitomp ,
|
||||||
|
.IR btomp ,
|
||||||
and
|
and
|
||||||
.IR btomp .
|
.IR dtomp .
|
||||||
These functions, in addition to
|
These functions, in addition to
|
||||||
.I mpnew
|
.I mpnew
|
||||||
and
|
and
|
||||||
|
@ -474,7 +481,7 @@ is
|
||||||
.BR nil ,
|
.BR nil ,
|
||||||
a new integer is allocated and returned as the result.
|
a new integer is allocated and returned as the result.
|
||||||
.PP
|
.PP
|
||||||
The integer conversions are:
|
The integer (and floating point) conversions are:
|
||||||
.TF Mptouv
|
.TF Mptouv
|
||||||
.TP
|
.TP
|
||||||
.I mptoui
|
.I mptoui
|
||||||
|
@ -500,12 +507,23 @@ The integer conversions are:
|
||||||
.TP
|
.TP
|
||||||
.I vtomp
|
.I vtomp
|
||||||
.BR "vlong" -> mpint
|
.BR "vlong" -> mpint
|
||||||
|
.TP
|
||||||
|
.I mptod
|
||||||
|
.BR mpint -> "double"
|
||||||
|
.TP
|
||||||
|
.I dtomp
|
||||||
|
.BR "double" -> mpint
|
||||||
.PD
|
.PD
|
||||||
.PP
|
.PP
|
||||||
When converting to the base integer types, if the integer is too large,
|
When converting to the base integer types, if the integer is too large,
|
||||||
the largest integer of the appropriate sign
|
the largest integer of the appropriate sign
|
||||||
and size is returned.
|
and size is returned.
|
||||||
.PP
|
.PP
|
||||||
|
When converting to and from floating point, results are rounded using IEEE 754 "round to nearest".
|
||||||
|
If the integer is too large in magnitude,
|
||||||
|
.I mptod
|
||||||
|
returns infinity of the appropriate sign.
|
||||||
|
.PP
|
||||||
The mathematical functions are:
|
The mathematical functions are:
|
||||||
.TF mpmagadd
|
.TF mpmagadd
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -42,6 +42,7 @@ FILES=\
|
||||||
cnfield\
|
cnfield\
|
||||||
gmfield\
|
gmfield\
|
||||||
mplogic\
|
mplogic\
|
||||||
|
mptod\
|
||||||
|
|
||||||
ALLOFILES=${FILES:%=%.$O}
|
ALLOFILES=${FILES:%=%.$O}
|
||||||
# cull things in the per-machine directories from this list
|
# cull things in the per-machine directories from this list
|
||||||
|
|
83
sys/src/libmp/port/mptod.c
Normal file
83
sys/src/libmp/port/mptod.c
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#include "os.h"
|
||||||
|
#include <mp.h>
|
||||||
|
#include "dat.h"
|
||||||
|
|
||||||
|
double
|
||||||
|
mptod(mpint *a)
|
||||||
|
{
|
||||||
|
u64int v;
|
||||||
|
mpdigit w, r;
|
||||||
|
int sf, i, n, m, s;
|
||||||
|
FPdbleword x;
|
||||||
|
|
||||||
|
if(a->top == 0) return 0.0;
|
||||||
|
sf = mpsignif(a);
|
||||||
|
if(sf > 1024) return Inf(a->sign);
|
||||||
|
i = a->top - 1;
|
||||||
|
v = a->p[i];
|
||||||
|
n = sf & Dbits - 1;
|
||||||
|
n |= n - 1 & Dbits;
|
||||||
|
r = 0;
|
||||||
|
if(n > 54){
|
||||||
|
s = n - 54;
|
||||||
|
r = v & (1<<s) - 1;
|
||||||
|
v >>= s;
|
||||||
|
}
|
||||||
|
while(n < 54){
|
||||||
|
if(--i < 0)
|
||||||
|
w = 0;
|
||||||
|
else
|
||||||
|
w = a->p[i];
|
||||||
|
m = 54 - n;
|
||||||
|
if(m > Dbits) m = Dbits;
|
||||||
|
s = Dbits - m & Dbits - 1;
|
||||||
|
v = v << m | w >> s;
|
||||||
|
r = w & (1<<s) - 1;
|
||||||
|
n += m;
|
||||||
|
}
|
||||||
|
if((v & 3) == 1){
|
||||||
|
while(--i >= 0)
|
||||||
|
r |= a->p[i];
|
||||||
|
if(r != 0)
|
||||||
|
v++;
|
||||||
|
}else
|
||||||
|
v++;
|
||||||
|
v >>= 1;
|
||||||
|
while((v >> 53) != 0){
|
||||||
|
v >>= 1;
|
||||||
|
if(++sf > 1024)
|
||||||
|
return Inf(a->sign);
|
||||||
|
}
|
||||||
|
x.lo = v;
|
||||||
|
x.hi = (u32int)(v >> 32) & (1<<20) - 1 | sf + 1022 << 20 | a->sign & 1<<31;
|
||||||
|
return x.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpint *
|
||||||
|
dtomp(double d, mpint *a)
|
||||||
|
{
|
||||||
|
FPdbleword x;
|
||||||
|
uvlong v;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
if(a == nil)
|
||||||
|
a = mpnew(0);
|
||||||
|
x.x = d;
|
||||||
|
e = x.hi >> 20 & 2047;
|
||||||
|
assert(e != 2047);
|
||||||
|
if(e < 1022){
|
||||||
|
mpassign(mpzero, a);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
v = x.lo | (uvlong)(x.hi & (1<<20) - 1) << 32 | 1ULL<<52;
|
||||||
|
if(e < 1075){
|
||||||
|
v += (1ULL<<1074 - e) - (~v >> 1075 - e & 1);
|
||||||
|
v >>= 1075 - e;
|
||||||
|
}
|
||||||
|
uvtomp(v, a);
|
||||||
|
if(e > 1075)
|
||||||
|
mpleft(a, e - 1075, a);
|
||||||
|
if((int)x.hi < 0)
|
||||||
|
a->sign = -1;
|
||||||
|
return a;
|
||||||
|
}
|
Loading…
Reference in a new issue