From 54222586fc769389928f40caffdc7538103085d7 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Sat, 11 Oct 2003 18:31:20 +0000 Subject: Division and modulus operator (~). From hugh@. --- usr.bin/dc/bcode.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- usr.bin/dc/dc.1 | 13 +++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) (limited to 'usr.bin/dc') 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 @@ -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 @@ -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 }, @@ -987,6 +989,48 @@ bmod(void) 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(b); +} + static void bexp(void) { 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 -- cgit v1.2.3