mirror of
https://github.com/vale981/arb
synced 2025-03-05 09:21:38 -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)
|
||||
{
|
||||
bc = exp - val;
|
||||
|
||||
/* If exactly one excess bit, there is a tie; the rounding
|
||||
direction is determined by the bit to the left of the
|
||||
truncation point. */
|
||||
if (bc - 1 == prec)
|
||||
if (exp - val - 1 == prec)
|
||||
{
|
||||
increment = (x[val_limbs] >> val_bits) & 1;
|
||||
}
|
||||
|
|
|
@ -28,23 +28,31 @@
|
|||
int
|
||||
arf_mul_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
||||
{
|
||||
fmpr_t a, b;
|
||||
slong r;
|
||||
if (rnd == ARF_RND_NEAR)
|
||||
{
|
||||
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(b);
|
||||
fmpr_init(a);
|
||||
fmpr_init(b);
|
||||
|
||||
arf_get_fmpr(a, x);
|
||||
arf_get_fmpr(b, y);
|
||||
arf_get_fmpr(a, x);
|
||||
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(b);
|
||||
fmpr_clear(a);
|
||||
fmpr_clear(b);
|
||||
|
||||
return (r == FMPR_RESULT_EXACT) ? 0 : 1;
|
||||
return (r == FMPR_RESULT_EXACT) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
|
@ -77,12 +85,13 @@ int main()
|
|||
if (n_randint(state, 50) == 0)
|
||||
prec = ARF_PREC_EXACT;
|
||||
|
||||
switch (n_randint(state, 4))
|
||||
switch (n_randint(state, 5))
|
||||
{
|
||||
case 0: rnd = ARF_RND_DOWN; break;
|
||||
case 1: rnd = ARF_RND_UP; 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))
|
||||
|
|
|
@ -68,12 +68,13 @@ int main()
|
|||
if (n_randint(state, 10))
|
||||
prec = ARF_PREC_EXACT;
|
||||
|
||||
switch (n_randint(state, 4))
|
||||
switch (n_randint(state, 5))
|
||||
{
|
||||
case 0: rnd = ARF_RND_DOWN; break;
|
||||
case 1: rnd = ARF_RND_UP; 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))
|
||||
|
|
|
@ -68,12 +68,13 @@ int main()
|
|||
if (n_randint(state, 10) == 0)
|
||||
prec = ARF_PREC_EXACT;
|
||||
|
||||
switch (n_randint(state, 4))
|
||||
switch (n_randint(state, 5))
|
||||
{
|
||||
case 0: rnd = ARF_RND_DOWN; break;
|
||||
case 1: rnd = ARF_RND_UP; 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))
|
||||
|
|
|
@ -68,12 +68,13 @@ int main()
|
|||
if (n_randint(state, 10) == 0)
|
||||
prec = ARF_PREC_EXACT;
|
||||
|
||||
switch (n_randint(state, 4))
|
||||
switch (n_randint(state, 5))
|
||||
{
|
||||
case 0: rnd = ARF_RND_DOWN; break;
|
||||
case 1: rnd = ARF_RND_UP; 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))
|
||||
|
|
|
@ -28,23 +28,31 @@
|
|||
int
|
||||
arf_mul_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
|
||||
{
|
||||
fmpr_t a, b;
|
||||
slong r;
|
||||
if (rnd == ARF_RND_NEAR)
|
||||
{
|
||||
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(b);
|
||||
fmpr_init(a);
|
||||
fmpr_init(b);
|
||||
|
||||
arf_get_fmpr(a, x);
|
||||
arf_get_fmpr(b, y);
|
||||
arf_get_fmpr(a, x);
|
||||
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(b);
|
||||
fmpr_clear(a);
|
||||
fmpr_clear(b);
|
||||
|
||||
return (r == FMPR_RESULT_EXACT) ? 0 : 1;
|
||||
return (r == FMPR_RESULT_EXACT) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
|
@ -77,12 +85,13 @@ int main()
|
|||
if (n_randint(state, 50) == 0)
|
||||
prec = ARF_PREC_EXACT;
|
||||
|
||||
switch (n_randint(state, 4))
|
||||
switch (n_randint(state, 5))
|
||||
{
|
||||
case 0: rnd = ARF_RND_DOWN; break;
|
||||
case 1: rnd = ARF_RND_UP; 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))
|
||||
|
|
|
@ -529,6 +529,7 @@ Addition and multiplication
|
|||
|
||||
Sets `z = x \times y`, rounded to *prec* bits in the direction specified by *rnd*,
|
||||
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)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue