summaryrefslogtreecommitdiff
path: root/usr.bin/dc
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2003-10-11 18:31:20 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2003-10-11 18:31:20 +0000
commit54222586fc769389928f40caffdc7538103085d7 (patch)
tree9ff8c7c17722a37db0c161e467d3dadd39374afa /usr.bin/dc
parentb8729f3c1afbf9b251e813f8aae3992e476dc8b6 (diff)
Division and modulus operator (~). From hugh@.
Diffstat (limited to 'usr.bin/dc')
-rw-r--r--usr.bin/dc/bcode.c48
-rw-r--r--usr.bin/dc/dc.113
2 files changed, 57 insertions, 4 deletions
diff --git a/usr.bin/dc/bcode.c b/usr.bin/dc/bcode.c
index e3c34d48850..4d29e32c9c0 100644
--- a/usr.bin/dc/bcode.c
+++ b/usr.bin/dc/bcode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bcode.c,v 1.7 2003/09/30 18:27:01 otto Exp $ */
+/* $OpenBSD: bcode.c,v 1.8 2003/10/11 18:31:18 otto Exp $ */
/*
* Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
@@ -17,7 +17,7 @@
*/
#ifndef lint
-static const char rcsid[] = "$OpenBSD: bcode.c,v 1.7 2003/09/30 18:27:01 otto Exp $";
+static const char rcsid[] = "$OpenBSD: bcode.c,v 1.8 2003/10/11 18:31:18 otto Exp $";
#endif /* not lint */
#include <ssl/ssl.h>
@@ -85,6 +85,7 @@ static void bsub(void);
static void bmul(void);
static void bdiv(void);
static void bmod(void);
+static void bdivmod(void);
static void bexp(void);
static bool bsqrt_stop(const BIGNUM *, const BIGNUM *);
static void bsqrt(void);
@@ -145,6 +146,7 @@ static const struct jump_entry jump_table_data[] = {
{ '*', bmul },
{ '/', bdiv },
{ '%', bmod },
+ { '~', bdivmod },
{ '^', bexp },
{ 's', store },
{ 'S', store_stack },
@@ -988,6 +990,48 @@ bmod(void)
}
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(b);
+}
+
+static void
bexp(void)
{
struct number *a, *p;
diff --git a/usr.bin/dc/dc.1 b/usr.bin/dc/dc.1
index bbd0cca3627..77df20a1318 100644
--- a/usr.bin/dc/dc.1
+++ b/usr.bin/dc/dc.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: dc.1,v 1.6 2003/10/01 08:19:29 jmc Exp $
+.\" $OpenBSD: dc.1,v 1.7 2003/10/11 18:31:19 otto Exp $
.\"
.\" Copyright (C) Caldera International Inc. 2001-2002.
.\" All rights reserved.
@@ -81,7 +81,7 @@ It may be preceded by an underscore
to input a negative number.
A number may contain a single decimal point.
A number may also contain the characters A\-F, with the values 10\-15.
-.It Cm "+ - / * % ^"
+.It Cm "+ - / * % ~ ^"
The
top two values on the stack are added
(+),
@@ -90,6 +90,7 @@ subtracted
multiplied (*),
divided (/),
remaindered (%),
+divided and remaindered (~),
or exponentiated (^).
The two entries are popped off the stack;
the result is pushed on the stack in their place.
@@ -125,6 +126,14 @@ If the exponent is negative, the scale of the result is the scale
defined by the
.Ar k
operation.
+.Pp
+In the case of the division and modulus operator (~),
+the resultant quotient is pushed first followed by the remainder.
+This is a shorthand for the sequence:
+.Bd -literal -offset indent -compact
+x y / x y %
+.Ed
+The division and modulus operator is a non-portable extension.
.It Ic s Ns Ar x
The
top of the stack is popped and stored into