summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/bc/dc/numeric.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/bc/dc/numeric.c')
-rw-r--r--gnu/usr.bin/bc/dc/numeric.c595
1 files changed, 0 insertions, 595 deletions
diff --git a/gnu/usr.bin/bc/dc/numeric.c b/gnu/usr.bin/bc/dc/numeric.c
deleted file mode 100644
index 442bf660a51..00000000000
--- a/gnu/usr.bin/bc/dc/numeric.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * interface dc to the bc numeric routines
- *
- * Copyright (C) 1994, 1997, 1998 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 */
-/* In this particular implementation we just slather out some glue and
- * make use of bc's numeric routines.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#else
-# define UCHAR_MAX ((unsigned char)~0)
-#endif
-#include "bcdefs.h"
-#include "proto.h"
-#include "global.h"
-#include "dc.h"
-#include "dc-proto.h"
-
-#ifdef __GNUC__
-# define ATTRIB(x) __attribute__(x)
-#else
-# define ATTRIB(x)
-#endif
-
-/* there is no POSIX standard for dc, so we'll take the GNU definitions */
-int 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 ATTRIB((unused)) 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 ATTRIB((unused)) 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;
-}
-
-/* divide two dc_nums, place quotient into *quotient and remainder
- * into *remainder;
- * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
- */
-int
-dc_divrem DC_DECLARG((a, b, kscale, quotient, remainder))
- dc_num a DC_DECLSEP
- dc_num b DC_DECLSEP
- int kscale DC_DECLSEP
- dc_num *quotient DC_DECLSEP
- dc_num *remainder DC_DECLEND
-{
- init_num((bc_num *)quotient);
- init_num((bc_num *)remainder);
- if (bc_divmod(CastNum(a), CastNum(b),
- (bc_num *)quotient, (bc_num *)remainder, 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;
-}
-
-int
-dc_modexp DC_DECLARG((base, expo, mod, kscale, result))
- dc_num base DC_DECLSEP
- dc_num expo DC_DECLSEP
- dc_num mod DC_DECLSEP
- int kscale DC_DECLSEP
- dc_num *result DC_DECLEND
-{
- init_num((bc_num *)result);
- if (bc_raisemod(CastNum(base), CastNum(expo), CastNum(mod),
- (bc_num *)result, kscale)){
- if (is_zero(CastNum(mod)))
- 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_p is DC_TOSS then deallocate the value after use.
- */
-int
-dc_num2int DC_DECLARG((value, discard_p))
- dc_num value DC_DECLSEP
- dc_discard discard_p DC_DECLEND
-{
- long result;
-
- result = num2long(CastNum(value));
- if (discard_p == DC_TOSS)
- 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_p is DC_TOSS then deallocate the value after use.
- */
-int
-dc_tell_scale DC_DECLARG((value, discard_p))
- dc_num value DC_DECLSEP
- dc_discard discard_p DC_DECLEND
-{
- int kscale;
-
- kscale = CastNum(value)->n_scale;
- if (discard_p == DC_TOSS)
- 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_p is DC_WITHNL, terminate output with a '\n';
- * if discard_p is DC_TOSS then deallocate the value after use
- */
-void
-dc_out_num DC_DECLARG((value, obase, newline_p, discard_p))
- dc_num value DC_DECLSEP
- int obase DC_DECLSEP
- dc_newline newline_p DC_DECLSEP
- dc_discard discard_p DC_DECLEND
-{
- out_num(CastNum(value), obase, out_char);
- if (newline_p == DC_WITHNL)
- out_char('\n');
- if (discard_p == DC_TOSS)
- dc_free_num(&value);
-}
-
-/* dump out the absolute value of the integer part of a
- * dc_num as a byte stream, without any line wrapping;
- * if discard_p is DC_TOSS then deallocate the value after use
- */
-void
-dc_dump_num DC_DECLARG((value, discard_p))
- dc_num dcvalue DC_DECLSEP
- dc_discard discard_p DC_DECLEND
-{
- struct digit_stack { int digit; struct digit_stack *link;};
- struct digit_stack *top_of_stack = NULL;
- struct digit_stack *cur;
- struct digit_stack *next;
- bc_num value;
- bc_num obase;
- bc_num digit;
-
- init_num(&value);
- init_num(&obase);
- init_num(&digit);
-
- /* we only handle the integer portion: */
- bc_divide(CastNum(dcvalue), _one_, &value, 0);
- /* we only handle the absolute value: */
- value->n_sign = PLUS;
- /* we're done with the dcvalue parameter: */
- if (discard_p == DC_TOSS)
- dc_free_num(&dcvalue);
-
- int2num(&obase, 1+UCHAR_MAX);
- do {
- (void) bc_divmod(value, obase, &value, &digit, 0);
- cur = dc_malloc(sizeof *cur);
- cur->digit = (int)num2long(digit);
- cur->link = top_of_stack;
- top_of_stack = cur;
- } while (!is_zero(value));
-
- for (cur=top_of_stack; cur; cur=next) {
- putchar(cur->digit);
- next = cur->link;
- free(cur);
- }
-
- free_num(&digit);
- free_num(&obase);
- 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 numeric.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 enough 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
- vsnprintf (error_mesg, sizeof 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
- vsnprintf (error_mesg, sizeof error_mesg, mesg, args);
- va_end (args);
-
- fprintf (stderr, "Runtime warning: %s\n", error_mesg);
-}