Finish import of dc from bc-1.04. Remove files no longer needed.
This commit is contained in:
parent
bc4e66aef9
commit
aa048f315c
@ -1,9 +1,10 @@
|
||||
# $NetBSD: Makefile,v 1.2 1995/04/23 07:58:29 cgd Exp $
|
||||
# $NetBSD: Makefile,v 1.3 1997/04/29 00:40:23 phil Exp $
|
||||
|
||||
PROG= dc
|
||||
CFLAGS+=-D_POSIX_SOURCE -I${.CURDIR} -I${.CURDIR}/../bc
|
||||
|
||||
SRCS= array.c dc-number.c number.c eval.c misc.c stack.c string.c
|
||||
SRCS= array.c dc.c eval.c misc.c numeric.c stack.c string.c \
|
||||
number.c getopt.c getopt1.c
|
||||
|
||||
.PATH: ${.CURDIR}/../bc
|
||||
|
||||
|
@ -1,493 +0,0 @@
|
||||
/*
|
||||
* interface dc to the bc numeric routines
|
||||
*
|
||||
* Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can either send email to this
|
||||
* program's author (see below) or write to: The Free Software Foundation,
|
||||
* Inc.; 675 Mass Ave. Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* This should be the only module that knows the internals of type dc_num */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "bcdefs.h"
|
||||
#include "proto.h"
|
||||
#include "global.h"
|
||||
#include "dc.h"
|
||||
#include "dc-proto.h"
|
||||
|
||||
/* Variable needed by bc's number.c. */
|
||||
char std_only = FALSE;
|
||||
|
||||
/* convert an opaque dc_num into a real bc_num */
|
||||
#define CastNum(x) ((bc_num)(x))
|
||||
|
||||
/* add two dc_nums, place into *result;
|
||||
* return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
|
||||
*/
|
||||
int
|
||||
dc_add DC_DECLARG((a, b, kscale, result))
|
||||
dc_num a DC_DECLSEP
|
||||
dc_num b DC_DECLSEP
|
||||
int kscale DC_DECLSEP
|
||||
dc_num *result DC_DECLEND
|
||||
{
|
||||
init_num((bc_num *)result);
|
||||
bc_add(CastNum(a), CastNum(b), (bc_num *)result, 0);
|
||||
return DC_SUCCESS;
|
||||
}
|
||||
|
||||
/* subtract two dc_nums, place into *result;
|
||||
* return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
|
||||
*/
|
||||
int
|
||||
dc_sub DC_DECLARG((a, b, kscale, result))
|
||||
dc_num a DC_DECLSEP
|
||||
dc_num b DC_DECLSEP
|
||||
int kscale DC_DECLSEP
|
||||
dc_num *result DC_DECLEND
|
||||
{
|
||||
init_num((bc_num *)result);
|
||||
bc_sub(CastNum(a), CastNum(b), (bc_num *)result, 0);
|
||||
return DC_SUCCESS;
|
||||
}
|
||||
|
||||
/* multiply two dc_nums, place into *result;
|
||||
* return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
|
||||
*/
|
||||
int
|
||||
dc_mul DC_DECLARG((a, b, kscale, result))
|
||||
dc_num a DC_DECLSEP
|
||||
dc_num b DC_DECLSEP
|
||||
int kscale DC_DECLSEP
|
||||
dc_num *result DC_DECLEND
|
||||
{
|
||||
init_num((bc_num *)result);
|
||||
bc_multiply(CastNum(a), CastNum(b), (bc_num *)result, kscale);
|
||||
return DC_SUCCESS;
|
||||
}
|
||||
|
||||
/* divide two dc_nums, place into *result;
|
||||
* return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
|
||||
*/
|
||||
int
|
||||
dc_div DC_DECLARG((a, b, kscale, result))
|
||||
dc_num a DC_DECLSEP
|
||||
dc_num b DC_DECLSEP
|
||||
int kscale DC_DECLSEP
|
||||
dc_num *result DC_DECLEND
|
||||
{
|
||||
init_num((bc_num *)result);
|
||||
if (bc_divide(CastNum(a), CastNum(b), (bc_num *)result, kscale)){
|
||||
fprintf(stderr, "%s: divide by zero\n", progname);
|
||||
return DC_DOMAIN_ERROR;
|
||||
}
|
||||
return DC_SUCCESS;
|
||||
}
|
||||
|
||||
/* place the reminder of dividing a by b into *result;
|
||||
* return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
|
||||
*/
|
||||
int
|
||||
dc_rem DC_DECLARG((a, b, kscale, result))
|
||||
dc_num a DC_DECLSEP
|
||||
dc_num b DC_DECLSEP
|
||||
int kscale DC_DECLSEP
|
||||
dc_num *result DC_DECLEND
|
||||
{
|
||||
init_num((bc_num *)result);
|
||||
if (bc_modulo(CastNum(a), CastNum(b), (bc_num *)result, kscale)){
|
||||
fprintf(stderr, "%s: remainder by zero\n", progname);
|
||||
return DC_DOMAIN_ERROR;
|
||||
}
|
||||
return DC_SUCCESS;
|
||||
}
|
||||
|
||||
/* place the result of exponentiationg a by b into *result;
|
||||
* return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
|
||||
*/
|
||||
int
|
||||
dc_exp DC_DECLARG((a, b, kscale, result))
|
||||
dc_num a DC_DECLSEP
|
||||
dc_num b DC_DECLSEP
|
||||
int kscale DC_DECLSEP
|
||||
dc_num *result DC_DECLEND
|
||||
{
|
||||
init_num((bc_num *)result);
|
||||
bc_raise(CastNum(a), CastNum(b), (bc_num *)result, kscale);
|
||||
return DC_SUCCESS;
|
||||
}
|
||||
|
||||
/* take the square root of the value, place into *result;
|
||||
* return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
|
||||
*/
|
||||
int
|
||||
dc_sqrt DC_DECLARG((value, kscale, result))
|
||||
dc_num value DC_DECLSEP
|
||||
int kscale DC_DECLSEP
|
||||
dc_num *result DC_DECLEND
|
||||
{
|
||||
bc_num tmp;
|
||||
|
||||
tmp = copy_num(CastNum(value));
|
||||
if (!bc_sqrt(&tmp, kscale)){
|
||||
fprintf(stderr, "%s: square root of negative number\n", progname);
|
||||
free_num(&tmp);
|
||||
return DC_DOMAIN_ERROR;
|
||||
}
|
||||
*((bc_num *)result) = tmp;
|
||||
return DC_SUCCESS;
|
||||
}
|
||||
|
||||
/* compare dc_nums a and b;
|
||||
* return a negative value if a < b;
|
||||
* return a positive value if a > b;
|
||||
* return zero value if a == b
|
||||
*/
|
||||
int
|
||||
dc_compare DC_DECLARG((a, b))
|
||||
dc_num a DC_DECLSEP
|
||||
dc_num b DC_DECLEND
|
||||
{
|
||||
return bc_compare(CastNum(a), CastNum(b));
|
||||
}
|
||||
|
||||
/* attempt to convert a dc_num to its corresponding int value
|
||||
* If discard_flag is true then deallocate the value after use.
|
||||
*/
|
||||
int
|
||||
dc_num2int DC_DECLARG((value, discard_flag))
|
||||
dc_num value DC_DECLSEP
|
||||
dc_boolean discard_flag DC_DECLEND
|
||||
{
|
||||
long result;
|
||||
|
||||
result = num2long(CastNum(value));
|
||||
if (discard_flag)
|
||||
dc_free_num(&value);
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
/* convert a C integer value into a dc_num */
|
||||
/* For convenience of the caller, package the dc_num
|
||||
* into a dc_data result.
|
||||
*/
|
||||
dc_data
|
||||
dc_int2data DC_DECLARG((value))
|
||||
int value DC_DECLEND
|
||||
{
|
||||
dc_data result;
|
||||
|
||||
init_num((bc_num *)&result.v.number);
|
||||
int2num((bc_num *)&result.v.number, value);
|
||||
result.dc_type = DC_NUMBER;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* get a dc_num from some input stream;
|
||||
* input is a function which knows how to read the desired input stream
|
||||
* ibase is the input base (2<=ibase<=DC_IBASE_MAX)
|
||||
* *readahead will be set to the readahead character consumed while
|
||||
* looking for the end-of-number
|
||||
*/
|
||||
/* For convenience of the caller, package the dc_num
|
||||
* into a dc_data result.
|
||||
*/
|
||||
dc_data
|
||||
dc_getnum DC_DECLARG((input, ibase, readahead))
|
||||
int (*input) DC_PROTO((void)) DC_DECLSEP
|
||||
int ibase DC_DECLSEP
|
||||
int *readahead DC_DECLEND
|
||||
{
|
||||
bc_num base;
|
||||
bc_num result;
|
||||
bc_num build;
|
||||
bc_num tmp;
|
||||
bc_num divisor;
|
||||
dc_data full_result;
|
||||
int negative = 0;
|
||||
int digit;
|
||||
int decimal;
|
||||
int c;
|
||||
|
||||
init_num(&tmp);
|
||||
init_num(&build);
|
||||
init_num(&base);
|
||||
result = copy_num(_zero_);
|
||||
int2num(&base, ibase);
|
||||
c = (*input)();
|
||||
while (isspace(c))
|
||||
c = (*input)();
|
||||
if (c == '_' || c == '-'){
|
||||
negative = c;
|
||||
c = (*input)();
|
||||
}else if (c == '+'){
|
||||
c = (*input)();
|
||||
}
|
||||
while (isspace(c))
|
||||
c = (*input)();
|
||||
for (;;){
|
||||
if (isdigit(c))
|
||||
digit = c - '0';
|
||||
else if ('A' <= c && c <= 'F')
|
||||
digit = 10 + c - 'A';
|
||||
else
|
||||
break;
|
||||
c = (*input)();
|
||||
int2num(&tmp, digit);
|
||||
bc_multiply(result, base, &result, 0);
|
||||
bc_add(result, tmp, &result, 0);
|
||||
}
|
||||
if (c == '.'){
|
||||
free_num(&build);
|
||||
free_num(&tmp);
|
||||
divisor = copy_num(_one_);
|
||||
build = copy_num(_zero_);
|
||||
decimal = 0;
|
||||
for (;;){
|
||||
c = (*input)();
|
||||
if (isdigit(c))
|
||||
digit = c - '0';
|
||||
else if ('A' <= c && c <= 'F')
|
||||
digit = 10 + c - 'A';
|
||||
else
|
||||
break;
|
||||
int2num(&tmp, digit);
|
||||
bc_multiply(build, base, &build, 0);
|
||||
bc_add(build, tmp, &build, 0);
|
||||
bc_multiply(divisor, base, &divisor, 0);
|
||||
++decimal;
|
||||
}
|
||||
bc_divide(build, divisor, &build, decimal);
|
||||
bc_add(result, build, &result, 0);
|
||||
}
|
||||
/* Final work. */
|
||||
if (negative)
|
||||
bc_sub(_zero_, result, &result, 0);
|
||||
|
||||
free_num(&tmp);
|
||||
free_num(&build);
|
||||
free_num(&base);
|
||||
if (readahead)
|
||||
*readahead = c;
|
||||
full_result.v.number = (dc_num)result;
|
||||
full_result.dc_type = DC_NUMBER;
|
||||
return full_result;
|
||||
}
|
||||
|
||||
|
||||
/* return the "length" of the number */
|
||||
int
|
||||
dc_numlen DC_DECLARG((value))
|
||||
dc_num value DC_DECLEND
|
||||
{
|
||||
bc_num num = CastNum(value);
|
||||
|
||||
/* is this right??? */
|
||||
return num->n_len + num->n_scale;
|
||||
}
|
||||
|
||||
/* return the scale factor of the passed dc_num
|
||||
* If discard_flag is true then deallocate the value after use.
|
||||
*/
|
||||
int
|
||||
dc_tell_scale DC_DECLARG((value, discard_flag))
|
||||
dc_num value DC_DECLSEP
|
||||
dc_boolean discard_flag DC_DECLEND
|
||||
{
|
||||
int kscale;
|
||||
|
||||
kscale = CastNum(value)->n_scale;
|
||||
if (discard_flag)
|
||||
dc_free_num(&value);
|
||||
return kscale;
|
||||
}
|
||||
|
||||
|
||||
/* initialize the math subsystem */
|
||||
void
|
||||
dc_math_init DC_DECLVOID()
|
||||
{
|
||||
init_numbers();
|
||||
}
|
||||
|
||||
/* print out a dc_num in output base obase to stdout;
|
||||
* if newline is true, terminate output with a '\n';
|
||||
* if discard_flag is true then deallocate the value after use
|
||||
*/
|
||||
void
|
||||
dc_out_num DC_DECLARG((value, obase, newline, discard_flag))
|
||||
dc_num value DC_DECLSEP
|
||||
int obase DC_DECLSEP
|
||||
dc_boolean newline DC_DECLSEP
|
||||
dc_boolean discard_flag DC_DECLEND
|
||||
{
|
||||
out_num(CastNum(value), obase, out_char);
|
||||
if (newline)
|
||||
out_char('\n');
|
||||
if (discard_flag)
|
||||
dc_free_num(&value);
|
||||
}
|
||||
|
||||
|
||||
/* deallocate an instance of a dc_num */
|
||||
void
|
||||
dc_free_num DC_DECLARG((value))
|
||||
dc_num *value DC_DECLEND
|
||||
{
|
||||
free_num((bc_num *)value);
|
||||
}
|
||||
|
||||
/* return a duplicate of the number in the passed value */
|
||||
/* The mismatched data types forces the caller to deal with
|
||||
* bad dc_type'd dc_data values, and makes it more convenient
|
||||
* for the caller to not have to do the grunge work of setting
|
||||
* up a dc_type result.
|
||||
*/
|
||||
dc_data
|
||||
dc_dup_num DC_DECLARG((value))
|
||||
dc_num value DC_DECLEND
|
||||
{
|
||||
dc_data result;
|
||||
|
||||
++CastNum(value)->n_refs;
|
||||
result.v.number = value;
|
||||
result.dc_type = DC_NUMBER;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------\
|
||||
| The rest of this file consists of stubs for bc routines called by number.c |
|
||||
| so as to minimize the amount of bc code needed to build dc. |
|
||||
| The bulk of the code was just lifted straight out of the bc source. |
|
||||
\---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
|
||||
int out_col = 0;
|
||||
|
||||
/* Output routines: Write a character CH to the standard output.
|
||||
It keeps track of the number of characters output and may
|
||||
break the output with a "\<cr>". */
|
||||
|
||||
void
|
||||
out_char (ch)
|
||||
char ch;
|
||||
{
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
out_col = 0;
|
||||
putchar ('\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
out_col++;
|
||||
if (out_col == 70)
|
||||
{
|
||||
putchar ('\\');
|
||||
putchar ('\n');
|
||||
out_col = 1;
|
||||
}
|
||||
putchar (ch);
|
||||
}
|
||||
}
|
||||
|
||||
/* Malloc could not get enought memory. */
|
||||
|
||||
void
|
||||
out_of_memory()
|
||||
{
|
||||
dc_memfail();
|
||||
}
|
||||
|
||||
/* Runtime error will print a message and stop the machine. */
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
#ifdef __STDC__
|
||||
void
|
||||
rt_error (char *mesg, ...)
|
||||
#else
|
||||
void
|
||||
rt_error (mesg)
|
||||
char *mesg;
|
||||
#endif
|
||||
#else
|
||||
void
|
||||
rt_error (mesg, va_alist)
|
||||
char *mesg;
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
char error_mesg [255];
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
va_start (args, mesg);
|
||||
#else
|
||||
va_start (args);
|
||||
#endif
|
||||
vsprintf (error_mesg, mesg, args);
|
||||
va_end (args);
|
||||
|
||||
fprintf (stderr, "Runtime error: %s\n", error_mesg);
|
||||
}
|
||||
|
||||
|
||||
/* A runtime warning tells of some action taken by the processor that
|
||||
may change the program execution but was not enough of a problem
|
||||
to stop the execution. */
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
#ifdef __STDC__
|
||||
void
|
||||
rt_warn (char *mesg, ...)
|
||||
#else
|
||||
void
|
||||
rt_warn (mesg)
|
||||
char *mesg;
|
||||
#endif
|
||||
#else
|
||||
void
|
||||
rt_warn (mesg, va_alist)
|
||||
char *mesg;
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
char error_mesg [255];
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
va_start (args, mesg);
|
||||
#else
|
||||
va_start (args);
|
||||
#endif
|
||||
vsprintf (error_mesg, mesg, args);
|
||||
va_end (args);
|
||||
|
||||
fprintf (stderr, "Runtime warning: %s\n", error_mesg);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* dc version number
|
||||
*
|
||||
* Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can either send email to this
|
||||
* program's author (see below) or write to: The Free Software Foundation,
|
||||
* Inc.; 675 Mass Ave. Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define Version "dc 1.0"
|
@ -1,425 +0,0 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header
|
||||
@setfilename dc.info
|
||||
@settitle dc, an arbitrary precision calculator
|
||||
@c %**end of header
|
||||
|
||||
@c This file has the new style title page commands.
|
||||
@c Run `makeinfo' rather than `texinfo-format-buffer'.
|
||||
|
||||
@c smallbook
|
||||
|
||||
@c tex
|
||||
@c \overfullrule=0pt
|
||||
@c end tex
|
||||
|
||||
@c Combine indices.
|
||||
@synindex cp fn
|
||||
@syncodeindex vr fn
|
||||
@syncodeindex ky fn
|
||||
@syncodeindex pg fn
|
||||
@syncodeindex tp fn
|
||||
|
||||
@ifinfo
|
||||
This file documents @sc{dc}, an arbitrary precision calculator.
|
||||
|
||||
Published by the Free Software Foundation,
|
||||
675 Massachusetts Avenue,
|
||||
Cambridge, MA 02139 USA
|
||||
|
||||
Copyright (C) 1984 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
@ignore
|
||||
Permission is granted to process this file through TeX and print the
|
||||
results, provided the printed document carries copying permission
|
||||
notice identical to this one except for the removal of this paragraph
|
||||
(this paragraph not being relevant to the printed manual).
|
||||
|
||||
@end ignore
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Foundation.
|
||||
@end ifinfo
|
||||
|
||||
@setchapternewpage off
|
||||
|
||||
@titlepage
|
||||
@title dc, an arbitrary precision calculator
|
||||
|
||||
@author by Ken Pizzini
|
||||
@author manual by Richard Stallman
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1994 Free Software Foundation, Inc.
|
||||
|
||||
@sp 2
|
||||
Published by the Free Software Foundation, @*
|
||||
675 Massachusetts Avenue, @*
|
||||
Cambridge, MA 02139 USA
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Foundation.
|
||||
|
||||
@end titlepage
|
||||
@page
|
||||
|
||||
@node Top, Introduction, (dir), (dir)
|
||||
|
||||
@menu
|
||||
* Introduction:: Introduction
|
||||
* Printing Commands:: Printing Commands
|
||||
* Arithmetic:: Arithmetic
|
||||
* Stack Control:: Stack Control
|
||||
* Registers:: Registers
|
||||
* Parameters:: Parameters
|
||||
* Strings:: Strings
|
||||
* Status Inquiry:: Status Inquiry
|
||||
* Miscellaneous:: Other commands
|
||||
* Notes:: Notes
|
||||
@end menu
|
||||
|
||||
@node Introduction, Printing Commands, Top, Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Introduction
|
||||
|
||||
@sc{dc} is a reverse-polish desk calculator
|
||||
which supports unlimited precision arithmetic.
|
||||
It also allows you to define and call macros.
|
||||
Normally @sc{dc} reads from the standard input;
|
||||
if any command arguments are given to it, they are filenames,
|
||||
and @sc{dc} reads and executes the contents of the files
|
||||
before reading from standard input.
|
||||
All normal output is to standard output;
|
||||
all error messages are written to standard error.
|
||||
|
||||
To exit, use @samp{q}.
|
||||
@kbd{C-c} does not exit;
|
||||
it is used to abort macros that are looping, etc.
|
||||
(Currently this is not true; @kbd{C-c} does exit.)
|
||||
|
||||
A reverse-polish calculator stores numbers on a stack.
|
||||
Entering a number pushes it on the stack.
|
||||
Arithmetic operations pop arguments off the stack and push the results.
|
||||
|
||||
To enter a number in @sc{dc}, type the digits,
|
||||
with an optional decimal point.
|
||||
Exponential notation is not supported.
|
||||
To enter a negative number, begin the number with @samp{_}.
|
||||
@samp{-} cannot be used for this, as it is a binary operator
|
||||
for subtraction instead.
|
||||
To enter two numbers in succession,
|
||||
separate them with spaces or newlines.
|
||||
These have no meaning as commands.
|
||||
|
||||
@node Printing Commands, Arithmetic, Introduction, Top
|
||||
@chapter Printing Commands
|
||||
|
||||
@table @samp
|
||||
@item p
|
||||
Prints the value on the top of the stack,
|
||||
without altering the stack.
|
||||
A newline is printed after the value.
|
||||
|
||||
@item P
|
||||
Prints the value on the top of the stack, popping it off,
|
||||
and does not print a newline after.
|
||||
|
||||
@item f
|
||||
Prints the entire contents of the stack
|
||||
@c and the contents of all of the registers,
|
||||
without altering anything.
|
||||
This is a good command to use if you are lost or want
|
||||
to figure out what the effect of some command has been.
|
||||
@end table
|
||||
|
||||
@node Arithmetic, Stack Control, Printing Commands, Top
|
||||
@chapter Arithmetic
|
||||
|
||||
@table @samp
|
||||
@item +
|
||||
Pops two values off the stack, adds them, and pushes the result.
|
||||
The precision of the result is determined only
|
||||
by the values of the arguments, and is enough to be exact.
|
||||
|
||||
@item -
|
||||
Pops two values, subtracts the first one popped
|
||||
from the second one popped, and pushes the result.
|
||||
|
||||
@item *
|
||||
Pops two values, multiplies them, and pushes the result.
|
||||
The number of fraction digits in the result is controlled
|
||||
by the current precision value (see below) and does not
|
||||
depend on the values being multiplied.
|
||||
|
||||
@item /
|
||||
Pops two values, divides the second one popped
|
||||
from the first one popped, and pushes the result.
|
||||
The number of fraction digits is specified by the precision value.
|
||||
|
||||
@item %
|
||||
Pops two values,
|
||||
computes the remainder of the division that
|
||||
the @samp{/} command would do,
|
||||
and pushes that.
|
||||
The division is done with as many fraction digits
|
||||
as the precision value specifies,
|
||||
and the remainder is also computed with that many fraction digits.
|
||||
|
||||
@item ^
|
||||
Pops two values and exponentiates,
|
||||
using the first value popped as the exponent
|
||||
and the second popped as the base.
|
||||
The fraction part of the exponent is ignored.
|
||||
The precision value specifies the number of fraction
|
||||
digits in the result.
|
||||
|
||||
@item v
|
||||
Pops one value, computes its square root, and pushes that.
|
||||
The precision value specifies the number of fraction digits
|
||||
in the result.
|
||||
@end table
|
||||
|
||||
Most arithmetic operations are affected by the @emph{precision value},
|
||||
which you can set with the @samp{k} command.
|
||||
The default precision value is zero,
|
||||
which means that all arithmetic except for
|
||||
addition and subtraction produces integer results.
|
||||
|
||||
The remainder operation (@samp{%}) requires some explanation:
|
||||
applied to arguments @samp{a} and @samp{b}
|
||||
it produces @samp{a - (b * (a / b))},
|
||||
where @samp{a / b} is computed in the current precision.
|
||||
|
||||
@node Stack Control, Registers, Arithmetic, Top
|
||||
@chapter Stack Control
|
||||
|
||||
@table @samp
|
||||
@item c
|
||||
Clears the stack, rendering it empty.
|
||||
|
||||
@item d
|
||||
Duplicates the value on the top of the stack,
|
||||
pushing another copy of it.
|
||||
Thus, @samp{4d*p} computes 4 squared and prints it.
|
||||
@end table
|
||||
|
||||
@node Registers, Parameters, Stack Control, Top
|
||||
@chapter Registers
|
||||
|
||||
@sc{dc} provides 256 memory registers, each named by a single character.
|
||||
You can store a number in a register and retrieve it later.
|
||||
|
||||
@table @samp
|
||||
@item s@var{r}
|
||||
Pop the value off the top of the stack and
|
||||
store it into register @var{r}.
|
||||
|
||||
@item l@var{r}
|
||||
Copy the value in register @var{r},
|
||||
and push it onto the stack.
|
||||
This does not alter the contents of @var{r}.
|
||||
|
||||
Each register also contains its own stack.
|
||||
The current register value is the top of the register's stack.
|
||||
|
||||
@item S@var{r}
|
||||
Pop the value off the top of the (main) stack and
|
||||
push it onto the stack of register @var{r}.
|
||||
The previous value of the register becomes inaccessible.
|
||||
|
||||
@item L@var{r}
|
||||
Pop the value off the top of register @var{r}'s stack
|
||||
and push it onto the main stack.
|
||||
The previous value in register @var{r}'s stack, if any,
|
||||
is now accessible via the @samp{l@var{r}} command.
|
||||
@end table
|
||||
@c
|
||||
@c The @samp{f} command prints a list of all registers that have contents
|
||||
@c stored in them, together with their contents.
|
||||
@c Only the current contents of each register (the top of its stack)
|
||||
@c is printed.
|
||||
|
||||
@node Parameters, Strings, Registers, Top
|
||||
@chapter Parameters
|
||||
|
||||
@sc{dc} has three parameters that control its operation:
|
||||
the precision, the input radix, and the output radix.
|
||||
The precision specifies the number of fraction digits
|
||||
to keep in the result of most arithmetic operations.
|
||||
The input radix controls the interpretation of numbers typed in;
|
||||
@emph{all} numbers typed in use this radix.
|
||||
The output radix is used for printing numbers.
|
||||
|
||||
The input and output radices are separate parameters;
|
||||
you can make them unequal, which can be useful or confusing.
|
||||
The input radix must be between 2 and 36 inclusive.
|
||||
The output radix must be at least 2.
|
||||
The precision must be zero or greater.
|
||||
The precision is always measured in decimal digits,
|
||||
regardless of the current input or output radix.
|
||||
|
||||
@table @samp
|
||||
@item i
|
||||
Pops the value off the top of the stack
|
||||
and uses it to set the input radix.
|
||||
|
||||
@item o
|
||||
Pops the value off the top of the stack
|
||||
and uses it to set the output radix.
|
||||
|
||||
@item k
|
||||
Pops the value off the top of the stack
|
||||
and uses it to set the precision.
|
||||
|
||||
@item I
|
||||
Pushes the current input radix on the stack.
|
||||
|
||||
@item O
|
||||
Pushes the current output radix on the stack.
|
||||
|
||||
@item K
|
||||
Pushes the current precision on the stack.
|
||||
|
||||
@end table
|
||||
|
||||
@node Strings, Status Inquiry, Parameters, Top
|
||||
@chapter Strings
|
||||
|
||||
@sc{dc} can operate on strings as well as on numbers.
|
||||
The only things you can do with strings are print them
|
||||
and execute them as macros
|
||||
(which means that the contents of the string are processed as @sc{dc} commands).
|
||||
Both registers and the stack can hold strings,
|
||||
and @sc{dc} always knows whether any given object is a string or a number.
|
||||
Some commands such as arithmetic operations demand numbers
|
||||
as arguments and print errors if given strings.
|
||||
Other commands can accept either a number or a string;
|
||||
for example, the @samp{p} command can accept either and prints the object
|
||||
according to its type.
|
||||
|
||||
@table @samp
|
||||
@item [@var{characters}]
|
||||
Makes a string containing @var{characters} and pushes it on the stack.
|
||||
For example, @samp{[foo]P} prints the characters @samp{foo}
|
||||
(with no newline).
|
||||
|
||||
@item x
|
||||
Pops a value off the stack and executes it as a macro.
|
||||
Normally it should be a string;
|
||||
if it is a number, it is simply pushed back onto the stack.
|
||||
For example, @samp{[1p]x} executes the macro @samp{1p},
|
||||
which pushes 1 on the stack and prints @samp{1} on a separate line.
|
||||
|
||||
Macros are most often stored in registers;
|
||||
@samp{[1p]sa} stores a macro to print @samp{1} into register @samp{a},
|
||||
and @samp{lax} invokes the macro.
|
||||
|
||||
@item >@var{r}
|
||||
Pops two values off the stack and compares them
|
||||
assuming they are numbers,
|
||||
executing the contents of register @var{r} as a macro
|
||||
if the original top-of-stack is greater.
|
||||
Thus, @samp{1 2>a} will invoke register @samp{a}'s contents
|
||||
and @samp{2 1>a} will not.
|
||||
|
||||
@item <@var{r}
|
||||
Similar but invokes the macro if the original top-of-stack is less.
|
||||
|
||||
@item =@var{r}
|
||||
Similar but invokes the macro if the two numbers popped are equal.
|
||||
@c This can also be validly used to compare two strings for equality.
|
||||
|
||||
@item ?
|
||||
Reads a line from the terminal and executes it.
|
||||
This command allows a macro to request input from the user.
|
||||
|
||||
@item q
|
||||
During the execution of a macro,
|
||||
this command exits from the macro and also from the macro which invoked it.
|
||||
If called from the top level,
|
||||
or from a macro which was called directly from the top level,
|
||||
the @samp{q} command will cause @sc{dc} to exit.
|
||||
|
||||
@item Q
|
||||
Pops a value off the stack and uses it as a count
|
||||
of levels of macro execution to be exited.
|
||||
Thus, @samp{3Q} exits three levels.
|
||||
@end table
|
||||
|
||||
@node Status Inquiry, Miscellaneous, Strings, Top
|
||||
@chapter Status Inquiry
|
||||
|
||||
@table @samp
|
||||
@item Z
|
||||
Pops a value off the stack,
|
||||
calculates the number of digits it has
|
||||
(or number of characters, if it is a string)
|
||||
and pushes that number.
|
||||
|
||||
@item X
|
||||
Pops a value off the stack,
|
||||
calculates the number of fraction digits it has,
|
||||
and pushes that number.
|
||||
For a string, the value pushed is
|
||||
@c -1.
|
||||
0.
|
||||
|
||||
@item z
|
||||
Pushes the current stack depth;
|
||||
the number of objects on the stack
|
||||
before the execution of the @samp{z} command.
|
||||
@end table
|
||||
|
||||
@node Miscellaneous, Notes, Status Inquiry, Top
|
||||
@chapter Miscellaneous
|
||||
|
||||
@table @samp
|
||||
@item !
|
||||
Will run the rest of the line as a system command.
|
||||
|
||||
@item #
|
||||
Will interpret the rest of the line as a comment.
|
||||
|
||||
@item :@var{r}
|
||||
Will pop the top two values off of the stack.
|
||||
The old second-to-top value will be stored in the array @var{r},
|
||||
indexed by the old top-of-stack value.
|
||||
|
||||
@item ;@var{r}
|
||||
Pops the top-of-stack and uses it as an index into
|
||||
the array @var{r}.
|
||||
The selected value is then pushed onto the stack.
|
||||
@end table
|
||||
|
||||
@node Notes, , Miscellaneous, Top
|
||||
@chapter Notes
|
||||
|
||||
The array operations @samp{:} and @samp{;} are usually
|
||||
only used by traditional implementations of BC.
|
||||
(The GNU BC is self contained and does not need @sc{dc} to run.)
|
||||
The comment operator @samp{#} is a new command
|
||||
not found in traditional implementations of @sc{dc}.
|
||||
|
||||
@contents
|
||||
@bye
|
Loading…
Reference in New Issue
Block a user