mirror of
https://github.com/vale981/arb
synced 2025-03-06 01:41:39 -05:00
support ARF_RND_NEAR in arf_mul_* methods
This commit is contained in:
parent
bbdf4f9c52
commit
16f6ebd87b
7 changed files with 55 additions and 35 deletions
|
@ -79,12 +79,10 @@ _arf_set_round_mpn(arf_t y, slong * exp_shift, mp_srcptr x, mp_size_t xn,
|
||||||
}
|
}
|
||||||
else if (rnd == ARF_RND_NEAR)
|
else if (rnd == ARF_RND_NEAR)
|
||||||
{
|
{
|
||||||
bc = exp - val;
|
|
||||||
|
|
||||||
/* If exactly one excess bit, there is a tie; the rounding
|
/* If exactly one excess bit, there is a tie; the rounding
|
||||||
direction is determined by the bit to the left of the
|
direction is determined by the bit to the left of the
|
||||||
truncation point. */
|
truncation point. */
|
||||||
if (bc - 1 == prec)
|
if (exp - val - 1 == prec)
|
||||||
{
|
{
|
||||||
increment = (x[val_limbs] >> val_bits) & 1;
|
increment = (x[val_limbs] >> val_bits) & 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,23 +28,31 @@
|
||||||
int
|
int
|
||||||
arf_mul_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
arf_mul_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
||||||
{
|
{
|
||||||
fmpr_t a, b;
|
if (rnd == ARF_RND_NEAR)
|
||||||
slong r;
|
{
|
||||||
|
arf_mul(z, x, y, ARF_PREC_EXACT, rnd);
|
||||||
|
return arf_set_round(z, z, prec, rnd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fmpr_t a, b;
|
||||||
|
slong r;
|
||||||
|
|
||||||
fmpr_init(a);
|
fmpr_init(a);
|
||||||
fmpr_init(b);
|
fmpr_init(b);
|
||||||
|
|
||||||
arf_get_fmpr(a, x);
|
arf_get_fmpr(a, x);
|
||||||
arf_get_fmpr(b, y);
|
arf_get_fmpr(b, y);
|
||||||
|
|
||||||
r = fmpr_mul_naive(a, a, b, prec, rnd);
|
r = fmpr_mul_naive(a, a, b, prec, rnd);
|
||||||
|
|
||||||
arf_set_fmpr(z, a);
|
arf_set_fmpr(z, a);
|
||||||
|
|
||||||
fmpr_clear(a);
|
fmpr_clear(a);
|
||||||
fmpr_clear(b);
|
fmpr_clear(b);
|
||||||
|
|
||||||
return (r == FMPR_RESULT_EXACT) ? 0 : 1;
|
return (r == FMPR_RESULT_EXACT) ? 0 : 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
@ -77,12 +85,13 @@ int main()
|
||||||
if (n_randint(state, 50) == 0)
|
if (n_randint(state, 50) == 0)
|
||||||
prec = ARF_PREC_EXACT;
|
prec = ARF_PREC_EXACT;
|
||||||
|
|
||||||
switch (n_randint(state, 4))
|
switch (n_randint(state, 5))
|
||||||
{
|
{
|
||||||
case 0: rnd = ARF_RND_DOWN; break;
|
case 0: rnd = ARF_RND_DOWN; break;
|
||||||
case 1: rnd = ARF_RND_UP; break;
|
case 1: rnd = ARF_RND_UP; break;
|
||||||
case 2: rnd = ARF_RND_FLOOR; break;
|
case 2: rnd = ARF_RND_FLOOR; break;
|
||||||
default: rnd = ARF_RND_CEIL; break;
|
case 3: rnd = ARF_RND_CEIL; break;
|
||||||
|
default: rnd = ARF_RND_NEAR; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (n_randint(state, 5))
|
switch (n_randint(state, 5))
|
||||||
|
|
|
@ -68,12 +68,13 @@ int main()
|
||||||
if (n_randint(state, 10))
|
if (n_randint(state, 10))
|
||||||
prec = ARF_PREC_EXACT;
|
prec = ARF_PREC_EXACT;
|
||||||
|
|
||||||
switch (n_randint(state, 4))
|
switch (n_randint(state, 5))
|
||||||
{
|
{
|
||||||
case 0: rnd = ARF_RND_DOWN; break;
|
case 0: rnd = ARF_RND_DOWN; break;
|
||||||
case 1: rnd = ARF_RND_UP; break;
|
case 1: rnd = ARF_RND_UP; break;
|
||||||
case 2: rnd = ARF_RND_FLOOR; break;
|
case 2: rnd = ARF_RND_FLOOR; break;
|
||||||
default: rnd = ARF_RND_CEIL; break;
|
case 3: rnd = ARF_RND_CEIL; break;
|
||||||
|
default: rnd = ARF_RND_NEAR; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (n_randint(state, 2))
|
switch (n_randint(state, 2))
|
||||||
|
|
|
@ -68,12 +68,13 @@ int main()
|
||||||
if (n_randint(state, 10) == 0)
|
if (n_randint(state, 10) == 0)
|
||||||
prec = ARF_PREC_EXACT;
|
prec = ARF_PREC_EXACT;
|
||||||
|
|
||||||
switch (n_randint(state, 4))
|
switch (n_randint(state, 5))
|
||||||
{
|
{
|
||||||
case 0: rnd = ARF_RND_DOWN; break;
|
case 0: rnd = ARF_RND_DOWN; break;
|
||||||
case 1: rnd = ARF_RND_UP; break;
|
case 1: rnd = ARF_RND_UP; break;
|
||||||
case 2: rnd = ARF_RND_FLOOR; break;
|
case 2: rnd = ARF_RND_FLOOR; break;
|
||||||
default: rnd = ARF_RND_CEIL; break;
|
case 3: rnd = ARF_RND_CEIL; break;
|
||||||
|
default: rnd = ARF_RND_NEAR; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (n_randint(state, 2))
|
switch (n_randint(state, 2))
|
||||||
|
|
|
@ -68,12 +68,13 @@ int main()
|
||||||
if (n_randint(state, 10) == 0)
|
if (n_randint(state, 10) == 0)
|
||||||
prec = ARF_PREC_EXACT;
|
prec = ARF_PREC_EXACT;
|
||||||
|
|
||||||
switch (n_randint(state, 4))
|
switch (n_randint(state, 5))
|
||||||
{
|
{
|
||||||
case 0: rnd = ARF_RND_DOWN; break;
|
case 0: rnd = ARF_RND_DOWN; break;
|
||||||
case 1: rnd = ARF_RND_UP; break;
|
case 1: rnd = ARF_RND_UP; break;
|
||||||
case 2: rnd = ARF_RND_FLOOR; break;
|
case 2: rnd = ARF_RND_FLOOR; break;
|
||||||
default: rnd = ARF_RND_CEIL; break;
|
case 3: rnd = ARF_RND_CEIL; break;
|
||||||
|
default: rnd = ARF_RND_NEAR; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (n_randint(state, 2))
|
switch (n_randint(state, 2))
|
||||||
|
|
|
@ -28,23 +28,31 @@
|
||||||
int
|
int
|
||||||
arf_mul_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
arf_mul_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
||||||
{
|
{
|
||||||
fmpr_t a, b;
|
if (rnd == ARF_RND_NEAR)
|
||||||
slong r;
|
{
|
||||||
|
arf_mul(z, x, y, ARF_PREC_EXACT, rnd);
|
||||||
|
return arf_set_round(z, z, prec, rnd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fmpr_t a, b;
|
||||||
|
slong r;
|
||||||
|
|
||||||
fmpr_init(a);
|
fmpr_init(a);
|
||||||
fmpr_init(b);
|
fmpr_init(b);
|
||||||
|
|
||||||
arf_get_fmpr(a, x);
|
arf_get_fmpr(a, x);
|
||||||
arf_get_fmpr(b, y);
|
arf_get_fmpr(b, y);
|
||||||
|
|
||||||
r = fmpr_mul_naive(a, a, b, prec, rnd);
|
r = fmpr_mul_naive(a, a, b, prec, rnd);
|
||||||
|
|
||||||
arf_set_fmpr(z, a);
|
arf_set_fmpr(z, a);
|
||||||
|
|
||||||
fmpr_clear(a);
|
fmpr_clear(a);
|
||||||
fmpr_clear(b);
|
fmpr_clear(b);
|
||||||
|
|
||||||
return (r == FMPR_RESULT_EXACT) ? 0 : 1;
|
return (r == FMPR_RESULT_EXACT) ? 0 : 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
@ -77,12 +85,13 @@ int main()
|
||||||
if (n_randint(state, 50) == 0)
|
if (n_randint(state, 50) == 0)
|
||||||
prec = ARF_PREC_EXACT;
|
prec = ARF_PREC_EXACT;
|
||||||
|
|
||||||
switch (n_randint(state, 4))
|
switch (n_randint(state, 5))
|
||||||
{
|
{
|
||||||
case 0: rnd = ARF_RND_DOWN; break;
|
case 0: rnd = ARF_RND_DOWN; break;
|
||||||
case 1: rnd = ARF_RND_UP; break;
|
case 1: rnd = ARF_RND_UP; break;
|
||||||
case 2: rnd = ARF_RND_FLOOR; break;
|
case 2: rnd = ARF_RND_FLOOR; break;
|
||||||
default: rnd = ARF_RND_CEIL; break;
|
case 3: rnd = ARF_RND_CEIL; break;
|
||||||
|
default: rnd = ARF_RND_NEAR; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (n_randint(state, 5))
|
switch (n_randint(state, 5))
|
||||||
|
|
|
@ -529,6 +529,7 @@ Addition and multiplication
|
||||||
|
|
||||||
Sets `z = x \times y`, rounded to *prec* bits in the direction specified by *rnd*,
|
Sets `z = x \times y`, rounded to *prec* bits in the direction specified by *rnd*,
|
||||||
returning nonzero iff the operation is inexact.
|
returning nonzero iff the operation is inexact.
|
||||||
|
These methods support *ARF_RND_NEAR*.
|
||||||
|
|
||||||
.. function:: int arf_add(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
.. function:: int arf_add(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue