version 1.7, 2003/09/30 18:27:01 |
version 1.8, 2003/10/11 18:31:18 |
|
|
static void bmul(void); |
static void bmul(void); |
static void bdiv(void); |
static void bdiv(void); |
static void bmod(void); |
static void bmod(void); |
|
static void bdivmod(void); |
static void bexp(void); |
static void bexp(void); |
static bool bsqrt_stop(const BIGNUM *, const BIGNUM *); |
static bool bsqrt_stop(const BIGNUM *, const BIGNUM *); |
static void bsqrt(void); |
static void bsqrt(void); |
|
|
{ '*', bmul }, |
{ '*', bmul }, |
{ '/', bdiv }, |
{ '/', bdiv }, |
{ '%', bmod }, |
{ '%', bmod }, |
|
{ '~', bdivmod }, |
{ '^', bexp }, |
{ '^', bexp }, |
{ 's', store }, |
{ 's', store }, |
{ 'S', store_stack }, |
{ 'S', store_stack }, |
|
|
BN_CTX_free(ctx); |
BN_CTX_free(ctx); |
} |
} |
push_number(r); |
push_number(r); |
|
free_number(a); |
|
free_number(b); |
|
} |
|
|
|
static void |
|
bdivmod(void) |
|
{ |
|
struct number *a, *b; |
|
struct number *rdiv, *rmod; |
|
u_int scale; |
|
BN_CTX *ctx; |
|
|
|
a = pop_number(); |
|
if (a == NULL) { |
|
return; |
|
} |
|
b = pop_number(); |
|
if (b == NULL) { |
|
push_number(a); |
|
return; |
|
} |
|
|
|
rdiv = new_number(); |
|
rmod = new_number(); |
|
rdiv->scale = bmachine.scale; |
|
rmod->scale = max(b->scale, a->scale + bmachine.scale); |
|
scale = max(a->scale, b->scale); |
|
|
|
if (BN_is_zero(a->number)) |
|
warnx("divide by zero"); |
|
else { |
|
normalize(a, scale); |
|
normalize(b, scale + bmachine.scale); |
|
|
|
ctx = BN_CTX_new(); |
|
bn_checkp(ctx); |
|
bn_check(BN_div(rdiv->number, rmod->number, |
|
b->number, a->number, ctx)); |
|
BN_CTX_free(ctx); |
|
} |
|
push_number(rdiv); |
|
push_number(rmod); |
free_number(a); |
free_number(a); |
free_number(b); |
free_number(b); |
} |
} |