Category : C Source Code
Archive   : APM.ZIP
Filename : MISC.C

 
Output of file : MISC.C contained in archive : APM.ZIP
/******************************************************************************

Arbitrary Precision Math Library General Public License
(Written October 5, 1988)

Copyright (C) 1988 Lloyd Zusman, Master Byte Software, Los
Gatos, California. Everyone is permitted to copy and distribute
verbatim copies of this license, but changing it is not allowed.
You can also use this wording to make the terms for other programs.

The wording of this license is based on that of the
"GNU EMACS GENERAL PUBLIC LICENSE" by Richard Stallman,
Copyright (C) 1985, 1987, 1988, version of February 11, 1988,
but since some of the text has been changed, please be sure to
READ THIS CAREFULLY!

This general public license is intended to give everyone the right
to share the Arbitrary Precision Math Library (hereinafter referred to
as the "APM Library"). To make sure that you get the rights we want
you to have, I need to make restrictions that forbid anyone to deny
you these rights or to ask you to surrender the rights.

Specifically, we want to make sure that you have the right to give
away copies of the APM Library, that you receive source code or else
can get it if you want it, that you can change the APM Library or use
pieces of it in new programs, and that you know you can do these
things.

To make sure that everyone has such rights, we have to forbid you to
deprive anyone else of these rights. For example, if you distribute
copies of the APM Library, you must give the recipients all the
rights that you have. You must make sure that they, too, receive or
can get the source code. And you must tell them their rights.

Also, for our own protection, we must make certain that everyone
finds out that there is no warranty for the APM Library. If the APM
Library is modified by someone else and passed on, we want its
recipients to know that what they have is not what we distributed, so
that any problems introduced by others will not reflect on our
reputation.

Therefore we (Lloyd Zusman and Master Byte Software) make the
following terms which say what you must do to be allowed to
distribute or change the APM Library.

COPYING POLICIES

1. You may copy and distribute verbatim copies of the APM Library
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy a valid copyright
notice "Copyright (C) 1988 Lloyd Zusman, Master Byte Software, Los
Gatos, California" (or with whatever year is appropriate); keep intact
the notices on all files that refer to this License Agreement and to
the absence of any warranty; and give any other recipients of the the
APM Library program a copy of this License Agreement along with the
program. You may charge a distribution fee for the physical act of
transferring a copy.

2. You may modify your copy or copies of the APM Library source code or
any portion of it, and copy and distribute such modifications under
the terms of Paragraph 1 above, provided that you also do the following:

a) cause the modified files to carry prominent notices stating
that you changed the files and the date of any change; and

b) cause the whole of any work that you distribute or publish, that in
whole or in part contains or is a derivative of the APM Library or any
part thereof, to be licensed to all third parties on terms identical
to those contained in this License Agreement (except that you may
choose to grant more extensive warranty protection to some or all
third parties, at your option).

c) You may charge a distribution fee for the physical act of
transferring a copy, and you may at your option offer warranty
protection in exchange for a fee.

d) You may not charge a license fee for the whole of any work that
you distribute or publish, that in whole or in part contains or is
a derivative of the APM library or any part thereof, without the
express written permission of Lloyd Zusman and Master Byte Software;
whether this permission is granted for free or in return for goods
services, royalties, or other compensation will be determined
solely by Lloyd Zusman and Master Byte Software.

Mere aggregation of another unrelated program with this program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other program under the scope of these terms.

3. You may copy and distribute the APM Library (or a portion or
derivative of it, under Paragraph 2) in object code or executable form
under all the terms of Paragraphs 1 and 2 above provided that you also
do one of the following:

a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,

b) accompany it with a written offer, valid for at least three
years, to give any third party free (except for a nominal
shipping charge) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,

c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.)

For an executable file, complete source code means all the source code
for all modules it contains; but, as a special exception, it need not
include source code for modules which are standard libraries that
accompany the operating system on which the executable file runs.

4. You may not copy, sublicense, distribute or transfer the APM
Library except as expressly provided under this License Agreement.
Any attempt otherwise to copy, sublicense, distribute or transfer the
APM Library is void and your rights to use the APM Library under this
License agreement shall be automatically terminated. However, parties
who have received computer software programs from you with this
License Agreement will not have their licenses terminated so long as
such parties remain in full compliance.

5. If you wish to incorporate parts of the APM Library into other
programs whose distribution conditions are different, write to Lloyd
Zusman at Master Byte Software. We have not yet worked out a simple
rule that can be stated here, but we will often permit this. We will
be guided by the goals of (1) preserving the free status of all
derivatives of our free software; of (2) promoting the sharing and
reuse of software; and of (3) not allowing anyone to profit from the
use of our software without us also having the opportunity to share
in these profits.

Your comments and suggestions about our licensing policies and our
software are welcome! Please contact Lloyd Zusman, Master Byte
Software, 127 Wilder Ave., Los Gatos, California 95030, or call
(408) 395-5693.

NO WARRANTY

BECAUSE THE APM LIBRARY IS LICENSED FREE OF CHARGE, WE PROVIDE
ABSOLUTELY NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING, MASTER BYTE SOFTWARE,
LLOYD ZUSMAN AND/OR OTHER PARTIES PROVIDE THE APM LIBRARY "AS IS"
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE THE APM
LIBRARY PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
SERVICING, REPAIR OR CORRECTION.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL MASTER BYTE
SOFTWARE, LLOYD ZUSMAN, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND
REDISTRIBUTE THE APM LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
MASTER BYTE SOFTWARE) THE PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF
THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.

******************************************************************************/


/*
* Miscellaneous routines for the APM library.
*
* $Log: misc.c,v $
* Revision 1.0 88/10/05 12:38:14 ljz
* Initial release.
*
*/
#ifndef lint
static char rcsid[] = "$Header: misc.c,v 1.0 88/10/05 12:38:14 ljz Exp $";
#endif /* ! lint */

#include
#include "apm.h"
#include "apmlocal.h"

static FILE *APM_debug_file = (FILE *)NULL;

APM
apm_init(init, scaleFactor, base)
long init;
int scaleFactor;
short base;
{
APM apm;
int ercode;

apm_errno = APM_OK;

apm = APM_alloc();
if (apm == (APM)NULL) {
APM_error(APM_ENOMEM);
return ((APM)NULL);
}

ercode = APM_parse_long(apm, init, base);
if (ercode < APM_OK) {
return ((APM)NULL);

}
ercode = APM_shift(apm, scaleFactor);
if (ercode < APM_OK) {
return ((APM)NULL);
}
return (apm);
}

int
apm_dispose(apm)
APM apm;
{
apm_errno = APM_OK;

return (APM_error(APM_free(apm)));
}

int
apm_garbage_collect()
{
apm_errno = APM_OK;

return (APM_error(APM_garbage_collect()));
}

int
apm_assign(result, value)
APM result;
APM value;
{
apm_errno = APM_OK;

ERR_RETURN(apm_validate(value));

if (result == value) {
return (APM_OK);
}

ERR_RETURN(APM_size(result, value->length));

APM_copy_bytes(result->data, value->data, value->length * sizeof(short));
result->sign = SIGNOF(value->sign);
result->base = value->base;
result->length = value->length;
result->dp = value->dp;
return (APM_OK);
}

int
apm_assign_long(result, longval, scaleFactor, base)
APM result;
long longval;
int scaleFactor;
short base;
{
static APM localApm = (APM)NULL;

apm_errno = APM_OK;

if (localApm == (APM)NULL) {
localApm = APM_alloc();
if (apm_errno < 0) {
return (APM_error(APM_ENOMEM));
}
}
ERR_RETURN(APM_parse_long(localApm, longval, base));
ERR_RETURN(APM_shift(localApm, scaleFactor));

return (APM_error(apm_assign(result, localApm)));
}

int
apm_assign_string(result, string, base)
APM result;
char *string;
short base;
{
apm_errno = APM_OK;

return (APM_error(APM_parse_string(result, string, base)));
}

int
apm_round(result, apm, dp)
APM result;
APM apm;
int dp;
{
static APM localApm1 = (APM)NULL;
static APM localApm2 = (APM)NULL;

apm_errno = APM_OK;

if (dp < 0) {
return (APM_set_errno(APM_EPARM));
}

ERR_RETURN(APM_val_format(result));
ERR_RETURN(APM_val_format(apm));
ERR_RETURN(APM_val_base(apm->base));

ERR_RETURN(APM_trim(apm, 1, 0));

if (dp < 0 || dp >= apm->dp) {
return (apm_assign(result, apm));
}

if (localApm1 == (APM)NULL) {
localApm1 = APM_alloc();
if (localApm1 == (APM)NULL) {
return (APM_error(APM_ENOMEM));
}
}

if (localApm2 == (APM)NULL) {
localApm2 = APM_alloc();
if (localApm2 == (APM)NULL) {
return (APM_error(APM_ENOMEM));
}
}

if (apm->base == SPECIAL_BASE) {
ERR_RETURN(apm_assign_long(localApm1, 5L, -dp - 1, 10));
ERR_RETURN(apm_assign(localApm2, apm));
ERR_RETURN(APM_spec_to_norm(localApm2));
ERR_RETURN(apm_add(result, localApm2, localApm1));
ERR_RETURN(APM_setdp(localApm2, result, dp));
ERR_RETURN(apm_assign(result, localApm2));
ERR_RETURN(APM_norm_to_spec(result));
}
else {
ERR_RETURN(apm_assign_long(localApm1, (long)(apm->base / 2),
-dp - 1, apm->base));
ERR_RETURN(apm_add(localApm2, apm, localApm1));
ERR_RETURN(APM_setdp(result, localApm2, dp));
}

return (APM_set_errno(APM_trim(result, 1, 0)));
}

int
apm_convert(result, length, dp, round, leftjust, apm)
char *result;
int length;
int dp;
int round;
int leftjust;
APM apm;
{
static APM localApm1 = (APM)NULL;
static APM localApm2 = (APM)NULL;
static APM recursiveApm = (APM)NULL;
static char *localString = NULL;
static int localLen = 0;
int roffset;
int loffset;
int stringlen;
int dpos = -1;
int n;
char *string;

apm_errno = APM_OK;

if (result == NULL) {
return (APM_error(APM_ENULLVAL));
}
*result = '\0';

ERR_RETURN(APM_val_format(apm));
ERR_RETURN(APM_val_base(apm->base));

if (apm->data == NULL && apm->length > 0) {
return (APM_error(APM_ENULLVAL));
}
if (length <= 1) {
return (APM_error(APM_EPARM));
}

if (apm->length < 0) {
return (APM_error(APM_EPARM));
}

if (apm->base == SPECIAL_BASE) {
if (recursiveApm == (APM)NULL) {
recursiveApm = APM_alloc();
if (recursiveApm == (APM)NULL) {
return (APM_error(APM_ENOMEM));
}
}
ERR_RETURN(apm_assign(recursiveApm, apm));
ERR_RETURN(APM_spec_to_norm(recursiveApm));
return (apm_convert(result, length, dp, round, leftjust,
recursiveApm));
}

if (localApm1 == (APM)NULL) {
localApm1 = APM_alloc();
if (localApm1 == (APM)NULL) {
return (APM_error(APM_ENOMEM));
}
}


if (!round || dp < 0) {
ERR_RETURN(APM_setdp(localApm1, apm, dp));
}
else {
if (localApm2 == (APM)NULL) {
localApm2 = APM_alloc();
if (localApm2 == (APM)NULL) {
return (APM_error(APM_ENOMEM));
}
}
ERR_RETURN(apm_round(localApm2, apm, dp));
ERR_RETURN(APM_setdp(localApm1, localApm2, dp));
}

ERR_RETURN(APM_trim(localApm1, 1, 0));

if (localApm1->dp < 0) {
stringlen = localApm1->length - localApm1->dp;
}
else if (localApm1->length < localApm1->dp) {
stringlen = localApm1->dp + 2;
}
else {
stringlen = localApm1->length;
if (localApm1->dp > 0) {
dpos = localApm1->length - localApm1->dp;
++stringlen;
if (dpos == 0) {
++stringlen;
}
}
}
if (localApm1->sign < 0) {
++stringlen;
}
if (stringlen + 1 > localLen) {
localString = APM_alloc_mem(localString, stringlen + 1,
sizeof (char));
if (localString == NULL) {
return (APM_error(APM_ENOMEM));
}
localLen = stringlen + 1;
}

string = localString;
if (localApm1->sign < 0) {
*string++ = '-';
}
if (localApm1->length < localApm1->dp) {
*string++ = '0';
*string++ = '.';
for (n = localApm1->length; n < localApm1->dp; ++n) {
*string++ = '0';
}
}
if (dpos == 0) {
*string++ = '0';
}
string = APM_build_string(string, localApm1->data, localApm1->length,
dpos);
for (n = localApm1->dp; n < 0; ++n) {
*string++ = '0';
}
*string = '\0';

if (localString[0] == '\0') {
localString[0] = '0';
localString[1] = '\0';
stringlen = 1;
}

--length;
if (leftjust) {
roffset = 0;
loffset = 0;
if (length > stringlen) {
length = stringlen;
}
}
else if (stringlen >= length) {
roffset = 0;
loffset = stringlen - length;
}
else {
roffset = length - stringlen;
loffset = 0;
}

APM_copy_bytes(result + roffset, localString + loffset, length);
result[length] = '\0';
while (roffset-- > 0) {
result[roffset] = ' ';
}

if (length < stringlen) {
return (APM_error(APM_WTRUNC));
}
else {
return (APM_OK);
}
}

int
apm_scale(result, num, scaleFactor)
APM result;
APM num;
int scaleFactor;
{
int ercode;

apm_errno = APM_OK;

ERR_RETURN(APM_val_format(result));
ERR_RETURN(apm_assign(result, num));

ercode = APM_shift(result, scaleFactor);
return (APM_error(ercode));
}

int
apm_compare(num1, num2)
APM num1;
APM num2;
{
static APM localApm = (APM)NULL;
int n;

apm_errno = APM_OK;

ERR_RETURN(apm_validate(num1));
ERR_RETURN(apm_validate(num2));

if (num1 == num2) {
return (0);
}

if (num1->base != num2->base) {
return (APM_error(APM_EBASE));
}

if (localApm == (APM)NULL) {
localApm = APM_alloc();
if (localApm == (APM)NULL) {
return (APM_error(APM_ENOMEM));
}
}

ERR_RETURN(apm_subtract(localApm, num1, num2));

for (n = 0; n < localApm->length; ++n) {
if (localApm->data[n] != 0) {
break;
}
}

if (n >= localApm->length) {
return (0);
}
else if (localApm->sign >= 0) {
return (1);
}
else {
return (-1);
}
}

int
apm_compare_long(apm, longval, scaleFactor, base)
APM apm;
long longval;
int scaleFactor;
short base;
{
static APM localApm = (APM)NULL;
int comparison;

apm_errno = APM_OK;

if (localApm == (APM)NULL) {
localApm = APM_alloc();
if (localApm == (APM)NULL) {
return (APM_error(APM_ENOMEM));
}
}

ERR_RETURN(apm_validate(apm));
ERR_RETURN(APM_parse_long(localApm, longval, base));
ERR_RETURN(APM_shift(localApm, scaleFactor));

comparison = apm_compare(apm, localApm);
if (apm_errno < 0) {
return (APM_error(apm_errno));
}
return (comparison);
}

int
apm_sign(apm)
APM apm;
{
apm_errno = APM_OK;

ERR_RETURN(apm_validate(apm));

return ((int)SIGNOF(apm->sign));
}

int
apm_absolute_value(result, apm)
APM result;
APM apm;
{
int sign;

apm_errno = APM_OK;

ERR_RETURN(APM_val_format(result));

if (result == apm) {
return (APM_error(APM_EOVERLAP));
}

sign = apm_sign(apm);
if (apm_errno < 0) {
return (APM_error(apm_errno));
}

if (sign < 0) {
return (APM_error(apm_negate(result, apm)));
}
else {
return (APM_error(apm_assign(result, apm)));
}
}

int
apm_negate(result, num)
APM result;
APM num;
{
apm_errno = APM_OK;

ERR_RETURN(APM_val_format(result));

if (result == num) {
return (APM_error(APM_EOVERLAP));
}
ERR_RETURN(apm_assign(result, num));

result->sign = -(SIGNOF(result->sign));

return (APM_OK);
}

int
apm_reciprocal(result, max_precision, num)
APM result;
int max_precision;
APM num;
{
static APM apmOne = (APM)NULL;

apm_errno = APM_OK;

ERR_RETURN(APM_val_format(result));
ERR_RETURN(apm_validate(num));

if (result == num) {
return (APM_error(APM_EOVERLAP));
}

if (apmOne == (APM)NULL) {
apmOne = apm_init(1L, 0, 0);
if (apmOne == (APM)NULL) {
return (APM_error(APM_ENOMEM));
}
}

apmOne->base = num->base;
return (apm_divide(result, max_precision, (APM)NULL, apmOne, num));
}

int
(*apm_error_func(newfunc))()
int (*newfunc)();
{
int (*oldfunc)() = APM_error_func;
APM_error_func = newfunc;
return (oldfunc);
}

int
apm_validate(apm)
APM apm;
{
apm_errno = APM_OK;

ERR_RETURN(APM_val_format(apm));
ERR_RETURN(APM_val_base(apm->base));

return (APM_OK);
}

FILE *
apm_debug_file(file)
FILE *file;
{
FILE *old = APM_debug_file;

APM_debug_file = file;
return (old);
}


  3 Responses to “Category : C Source Code
Archive   : APM.ZIP
Filename : MISC.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/