Patch level : no patch

Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Aggiunti i sorgenti per Greenleaf Math Library (gfm.dll)


git-svn-id: svn://10.65.10.50/trunk@10079 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
alex 2002-02-26 12:19:02 +00:00
parent 6f0360b17a
commit ba237a9d91
310 changed files with 31301 additions and 0 deletions

76
gfm/adate360.c Executable file
View File

@ -0,0 +1,76 @@
/* void AddDaysToDate360( m2, d2, y2, m1, d1, y1, ndays )
*
* ARGUMENTS
* int m1, d1, y1 - Specify a base date.
* int *m2, *d2, *y2 - Specify a date to be calculated
* int ndays - Number of days (+ or -) to be added to base
*
* DESCRIPTION
* A signed number of days (ndays) is added to the base date to form a
* second date which is transferred to the variables m2,d2,y2. If any of
* the arguments are NULL on input, an error results.
*
* Years < 100 are taken to be in 20th century.
*
* All years are considered to have 12 equal months of 30 days each for
* a total of 360 days.
*
* SIDE EFFECTS
* Changes d2, m2, y2.
*
* RETURNS
* None.
*
* POSSIBLE ERROR CODES
*
* GM_ARGVAL
* GM_NULLPOINTER
*
* AUTHOR
* Don Killen 03-Feb-1988 16:27:32
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
void AddDaysToDate360(m2,d2,y2,m1,d1,y1,ndays)
int m1,*m2,d1,*d2,y1,*y2,ndays;
{
long day;
_MacStart(GM_ADATE360);
if (d2==NULL||m2==NULL||y2==NULL) {
_MacErr(GM_NULLPOINTER);
_MacRetV;
}
if ( m1<1 || m1>12 || d1<1 || d1>31 || y1<1 || y1>9999 ) {
_MacErr(GM_ARGVAL);
_MacRetV;
}
day = (long) y1 * 360L + (long) ( (m1-1)*30 + (d1-1) + ndays);
/* computes days from Jan 1, Year 0 */
if (day<0L) { /* no negative years */
_MacErr(GM_ARGVAL);
_MacRetV;
}
/* changes to m2/d2/y2 */
*y2 = (int) (day / 360L);
day = day % 360L;
*m2 = (int) (day) / 30 + 1;
*d2 = (int) (day) % 30 + 1;
_MacRetV;
}

144
gfm/adate365.c Executable file
View File

@ -0,0 +1,144 @@
/* void AddDaysToDate365( m2, d2, y2, m1, d1, y1, ndays )
*
* ARGUMENTS
* int m1, d1, y1 - Specify a base date.
* int *m2, *d2, *y2 - Specify a date to be calculated
* int ndays - Number of days (+ or -) to be added to base
*
* DESCRIPTION
* A signed number of days (ndays) is added to the base date to form a
* second date which is transferred to the variables m2,d2,y2. If any of
* the arguments are NULL on input, an error results.
*
* Years < 100 are taken to be in 20th century.
*
* Years are considered to have 365 days. Leap years are considered here.
*
* SIDE EFFECTS
* Modified d2, m2, y2.
*
* RETURNS
* None.
*
* POSSIBLE ERROR CODES
*
* GM_ARGVAL
* GM_NULLPOINTER
*
* AUTHOR
* Don Killen 03-Feb-1988 16:27:32
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
void AddDaysToDate365(m2,d2,y2,m1,d1,y1,ndays)
int m1,*m2,d1,*d2,y1,*y2,ndays;
{
long n1;
int np, x, z, mt, dt=1, dp, ny, t1, t2;
mbool ly;
_MacStart(GM_ADATE365);
if (d2==NULL||m2==NULL||y2==NULL) {
_MacErr(GM_NULLPOINTER);
_MacRetV;
}
if ( m1<1 || m1>12 || d1<1 || d1>31 || y1<1 || y1>9999 ) {
_MacErr(GM_ARGVAL);
_MacRetV;
}
if (m1<=2) {
x=0;
z=y1-1;
}
else {
x=(4*m1 + 23) / 10;
z=y1;
}
/* compute day # */
n1 = (long) y1 * 365L + (long) (31*(m1-1) + d1 + z/4 - x)
+(long) ndays;
/* estimate year */
*y2 = (int) ((4L * n1) / 1461L);
np = (int) (n1 - ((long) (*y2) * 365L + (long) (((*y2) - 1) / 4)));
/* correct year estimate */
while (np<1) { /* year too large */
*y2 = (*y2)-1;
np = (int) (n1 - ((long)(*y2) * 365L +
(long) (((*y2)-1) / 4)));
}
if ( ((*y2) % 4) == 0)
ny = 366;
else
ny = 365;
while (np > ny ) { /* year too small */
*y2 = (*y2)+1;
np = (int) (n1 - ((long)(*y2) * 365L +
(long) (((*y2)-1) / 4)));
}
/* no leap year in 1700, 1800, 1900 */
if ((y1>=1700 && y1<=1900) || (*y2>=1700 && *y2<=1900)) {
t1 = (m1<=2) ? y1-1 : y1;
t2 = (np<60) ? (*y2)-1 : *y2;
if (np==60 && ndays<0)
t2--;
/* if y1 and y2 fall on different centuries, extra leap year counted */
np+= ((t2/100) - (t1/100));
if (np<1) {
*y2 = *y2-1;
*m2 = 12;
*d2 = 31;
_MacRetV;
}
if (np>366) {
*y2 = *y2+1;
*m2 = 1;
*d2 = 1;
_MacRetV;
}
}
/* handle Jan. & Feb. */
if (np <= 31) {
*m2 = 1;
*d2 = np;
_MacRetV;
}
/* check for leap year */
ly = ((*y2) % 4 == 0);
if (np <= 59 + (ly)) {
*m2 = 2;
*d2 = np - 31;
_MacRetV;
}
/* handle other months */
if (ly)
np--;
mt = 2;
do {
mt++;
dp = dt;
dt = np - 31 * (mt - 1) + (4 * mt + 23) / 10;
} while (dt>=1);
*m2 = mt-1;
*d2 = dp;
_MacRetV;
}

109
gfm/adatenly.c Executable file
View File

@ -0,0 +1,109 @@
/* void AddDaysToDate365NoLeapYear( m2, d2, y2, m1, d1, y1, ndays )
*
* ARGUMENTS
* int m1, d1, y1 - Specify a base date.
* int *m2, *d2, *y2 - Specify a date to be calculated
* int ndays - Number of days (+ or -) to be added to base
*
* DESCRIPTION
* A signed number of days (ndays) is added to the base date to form a
* second date which is transferred to the variables m2,d2,y2. If any of
* the arguments are NULL on input, an error results.
*
* Years < 100 are taken to be in 20th century.
*
* Years are considered to have 365 days. Leap years are considered here.
*
* SIDE EFFECTS
* Modified d2, m2, y2.
*
* RETURNS
* None.
*
* POSSIBLE ERROR CODES
*
* GM_ARGVAL
* GM_NULLPOINTER
*
* AUTHOR
* Don Killen 03-Feb-1988 16:27:32
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
void AddDaysToDate365NoLeapYear(m2,d2,y2,m1,d1,y1,ndays)
int m1,*m2,d1,*d2,y1,*y2,ndays;
{
long n1;
int np, x, mt, dt=1, dp, ny;
_MacStart(GM_ADATENLY);
if (d2==NULL||m2==NULL||y2==NULL) {
_MacErr(GM_NULLPOINTER);
_MacRetV;
}
if ( m1<1 || m1>12 || d1<1 || d1>31 || y1<1 || y1>9999 ) {
_MacErr(GM_ARGVAL);
_MacRetV;
}
if (m1<=2) {
x=0;
}
else {
x=(4*m1 + 23) / 10;
}
/* compute day # */
n1 = (long) y1 * 365L + (long) (31*(m1-1) + d1 - x)
+(long) ndays;
/* estimate year */
*y2 = (int) (n1 / 365L);
np = (int) (n1 - (long) (*y2) * 365L);
/* correct year estimate */
while (np<1) { /* year too large */
*y2 = (*y2)-1;
np = np + 365;
}
ny = 365;
while (np > ny) { /* year too small */
*y2 = (*y2)+1;
np = np-365;
}
/* handle Jan. & Feb. */
if (np <= 31) {
*m2 = 1;
*d2 = np;
_MacRetV;
}
if (np <= 59) {
*m2 = 2;
*d2 = np - 31;
_MacRetV;
}
/* handle other months */
mt = 2;
do {
mt++;
dp = dt;
dt = np - 31 * (mt - 1) + (4 * mt + 23) / 10;
} while (dt>=1);
*m2 = mt-1;
*d2 = dp;
_MacRetV;
}

64
gfm/addarr.c Executable file
View File

@ -0,0 +1,64 @@
/* DEC **AddDecimalArrays(pDst,pSrc1,pSrc2,n)
*
* ARGUMENT
* pDst is a ptr to the array of destination DEC pointers.
* pSrc1 and pSrc2 are ptrs to the arrays of source DEC pointers
* n is the number of elements in pSrc
*
* DESCRIPTION
* Sets pDst[i] = pSrc1[i] + pSrc2[i]. If pDst is null, tries to create a
* DEC structure, then add. If some of the pSrc structures
* are null, the non-null ones are still added.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns pointer to the new structure if successful, otherwise
* returns GM_NULLARR.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
* GM_ARGVAL
*
* AUTHOR
* Jared Levy
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC **AddDecimalArrays(pDst,pSrc1,pSrc2,n)
DEC **pDst;
DEC **pSrc1, **pSrc2;
int n;
{
int i;
/* source must be supplied !! */
_MacStart(GM_ADDARR);
if (!pSrc1 || !pSrc2 || !pDst) {
_MacErr(GM_NULLPOINTER);
_MacRet(GM_NULLARR);
}
if (n<0) {
_MacErr(GM_ARGVAL);
_MacRet(GM_NULLARR);
}
/* Add the numbers */
for (i=0; i<n; i++)
(void) AddDecimal(pDst[i], pSrc1[i], pSrc2[i]);
/* AddDecimal sets the error flag each time an error occurs */
_MacRet(pDst);
}

82
gfm/addarrd.c Executable file
View File

@ -0,0 +1,82 @@
/* DEC **AddDecimalToDecimalArray(pDst,pSrc1,pSrc2,n)
*
* ARGUMENT
* pDst is a ptr to the array of destination DEC pointers.
* pSrc1 is a ptr to the arrays of source DEC pointers
* pSrc2 is a ptr to another DEC.
* n is the number of elements in pSrc
*
* DESCRIPTION
* Sets pDst[i] = pSrc1[i] + pSrc2. If pDst is null, tries to create a
* DEC structure, then add. If some of the pSrc structures
* are null, the non-null ones are still added.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns pointer to the new structure if successful, otherwise
* returns GM_NULLARR.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
* GM_ARGVAL
*
* AUTHOR
* Jared Levy
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC **AddDecimalToDecimalArray(pDst,pSrc1,pSrc2,n)
DEC **pDst;
DEC **pSrc1, *pSrc2;
int n;
{
int i;
DEC dcop2, *cop2=&dcop2;
mbool copyback;
/* source must be supplied !! */
_MacStart(GM_ADDARRD);
_MacInVar(pSrc2, GM_NULLARR);
if (!pSrc1||!pDst) {
_MacErr(GM_NULLPOINTER);
_MacRet(GM_NULLARR);
}
if (n<=0) {
_MacErr(GM_ARGVAL);
_MacRet(GM_NULLARR);
}
/* Copy Src2 in case it is part of destination array */
_MacDCopy(cop2, pSrc2);
/* check if backwards copy is necessary */
copyback=(pDst > pSrc1);
/* Add the numbers */
i = copyback ? n-1 : 0;
while ((i<n) && (i>=0)) {
(void) AddDecimal(pDst[i], pSrc1[i], cop2);
/* AddDecimal sets the error flag each time an error occurs */
if (copyback)
i--;
else
i++;
}
_MacRet(pDst);
}

57
gfm/adddfd.c Executable file
View File

@ -0,0 +1,57 @@
/* DEC *AddDoubleToDecimal(pDst,pSrc1,l)
*
* ARGUMENT
* pDst is a pointer to the destination DEC structure.
* pSrc1 is a ptr to the source1 DEC structure.
* l is the double to be added to pSrc1
*
* DESCRIPTION
* Adds the value 'l' to pSrc1 and puts the result in dest DEC structure.
* The sum is calculated to the maximum possible accuracy.
*
* SIDE EFFECTS
* On overflow, the dest value is destroyed.
*
* RETURNS
* Returns a pointer to the dest structure unless overflow,
* when it returns a GM_NULL. On error, the error
* is in wGMError, unless an error was already there.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
* GM_CNVRE
*
* AUTHOR
* Andy Anderson 08-JUL-1987 1500
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *AddDoubleToDecimal(pDst,pSrc1,l)
DEC *pDst,*pSrc1;
double l;
{
DEC decS2, *pSrc2=&decS2, *pd;
_MacStart(GM_ADDDFD);
/* Convert the double to a DEC */
pSrc2=ConvDoubleToDecimal(pSrc2,l);
if (!pSrc2) {
if (pDst)
_MacDCopy(pDst, pSrc1);
_MacRet(GM_NULL);
}
pd = AddDecimal(pDst,pSrc1,pSrc2);
_MacRet(pd);
}

47
gfm/addid.c Executable file
View File

@ -0,0 +1,47 @@
/* DEC *AddIntToDecimal(pDst,pSrc1,l)
*
* ARGUMENT
* pDst is a pointer to the destination DEC structure.
* pSrc1 is a ptr to the source1 DEC structure.
* l is the int to be added to pSrc1
*
* DESCRIPTION
* Adds the value 'l' to pSrc1 and puts the result in dest DEC structure.
* The sum is calculated to the maximum possible accuracy.
*
* SIDE EFFECTS
* On overflow, the dest value is destroyed.
*
* RETURNS
* Returns a pointer to the dest structure unless overflow,
* when it returns a GM_NULL. On error, the error
* is in wGMError, unless an error was already there.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
*
* AUTHOR
* Andy Anderson 08-JUL-1987 1500
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *AddIntToDecimal(pDst,pSrc1,l)
DEC *pDst,*pSrc1;
int l;
{
DEC *t;
_MacStart(GM_ADDID);
t = AddLongToDecimal(pDst,pSrc1,(long) l);
_MacRet(t);
}

51
gfm/addld.c Executable file
View File

@ -0,0 +1,51 @@
/* DEC *AddLongToDecimal(pDst,pSrc1,l)
*
* ARGUMENT
* pDst is a pointer to the destination DEC structure.
* pSrc1 is a ptr to the source1 DEC structure.
* l is the long to be added to pSrc1
*
* DESCRIPTION
* Adds the value 'l' to pSrc1 and puts the result in dest DEC structure.
* The sum is calculated to the maximum possible accuracy.
*
* SIDE EFFECTS
* On overflow, the dest value is destroyed.
*
* RETURNS
* Returns a pointer to the dest structure unless overflow,
* when it returns a GM_NULL. On error, the error
* is in wGMError, unless an error was already there.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
*
* AUTHOR
* Andy Anderson 08-JUL-1987 1500
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *AddLongToDecimal(pDst,pSrc1,l)
DEC *pDst,*pSrc1;
long l;
{
DEC decS2, *pSrc2=&decS2, *pd;
_MacStart(GM_ADDLD);
/* Convert the long to a DEC int */
(void) ConvLongToDecimal(pSrc2,l);
pd = AddDecimal(pDst,pSrc1,pSrc2);
_MacRet(pd);
}

69
gfm/addstr.c Executable file
View File

@ -0,0 +1,69 @@
/* DEC
* AddAscii(pDst,pSrc1,pSrc2)
*
* ARGUMENT
* pDst is a pointer to the destination DEC structure
* pSrc1 is a pointer to source1 ASCII string
* pSrc2 is a pointer to source2 ASCII string
*
* DEpSrcIPTION
* Adds the value in pSrc1 (ASCII) to the value in pSrc2 (ASCII)
* and puts the result in pDst DEC structure
*
* SIDE EFFECTS
* On overflow, the dest value is indeterminate.
*
* RETURNS
* Returns a pointer to the dest structure unless overflow,
* otherwise, returns a GM_NULL(a C false). On error, the error
* is in wGMError, unless an error was already there.
*
* POSSIBLE ERROR CODES
*
* GM_NULLSTRING
* GM_NAN
* GM_CNVRE
* GM_CNVRW
*
* AUTHOR
* Kamy Rahimi 19-JAN-1987 10:14:48
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC* AddAscii(pDst,pSrc1,pSrc2)
DEC *pDst;
char *pSrc1,*pSrc2;
{
DEC t1,t2;
DEC *ps1,*ps2, *pd;
_MacStart( GM_ADDSTR );
ps1=&t1;
ps2=&t2;
ps1=ConvAsciiToDecimal(ps1,pSrc1);
if (!ps1)
_MacRet(GM_NULL);
ps2=ConvAsciiToDecimal(ps2,pSrc2);
if (!ps2)
_MacRet(GM_NULL);
pd = AddDecimal(pDst,ps1,ps2);
_MacRet(pd);
}

46
gfm/adduid.c Executable file
View File

@ -0,0 +1,46 @@
/* DEC *AddUnsToDecimal(pDst,pSrc1,l)
*
* ARGUMENT
* pDst is a pointer to the destination DEC structure.
* pSrc1 is a ptr to the source1 DEC structure.
* l is the int to be added to pSrc1
*
* DESCRIPTION
* Adds the value 'l' to pSrc1 and puts the result in dest DEC structure.
* The sum is calculated to the maximum possible accuracy.
*
* SIDE EFFECTS
* On overflow, the dest value is destroyed.
*
* RETURNS
* Returns a pointer to the dest structure unless overflow,
* when it returns a GM_NULL. On error, the error
* is in wGMError, unless an error was already there.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Andy Anderson 08-JUL-1987 1500
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *AddUnsToDecimal(pDst,pSrc1,l)
DEC *pDst,*pSrc1;
unsigned l;
{
DEC *t;
_MacStart(GM_ADDUID);
t = AddLongToDecimal(pDst,pSrc1,(long) l);
_MacRet(t);
}

50
gfm/adduld.c Executable file
View File

@ -0,0 +1,50 @@
/* DEC *AddUnsLongToDecimal(pDst,pSrc1,l)
*
* ARGUMENT
* *pDst is a pointer to the destination DEC structure.
* *pSrc1 is a ptr to the source1 DEC structure.
* l is the unsigned long to be added to pSrc1.
*
* DESCRIPTION
* Adds the value 'l' to pSrc1 and puts the result in dest DEC structure.
* The sum is calculated to the maximum possible accuracy.
*
* SIDE EFFECTS
* On overflow, the dest value is indeterminate.
*
* RETURNS
* Returns a pointer to the dest structure unless overflow,
* when it returns a GM_NULL. On error, the error
* is in wGMError, unless an error was already there.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
*
* AUTHOR
* Andy Anderson 08-JUL-1987 1500
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *AddUnsLongToDecimal(pDst,pSrc1,l)
DEC *pDst,*pSrc1;
unsigned long l;
{
DEC decTemp, *pSrc2=&decTemp, *pd;
_MacStart(GM_ADDULD);
/* Convert the unsigned long to a DEC int */
(void) ConvUnsLongToDecimal(pSrc2,l);
pd = AddDecimal(pDst,pSrc1,pSrc2);
_MacRet(pd);
}

55
gfm/advpmt.c Executable file
View File

@ -0,0 +1,55 @@
/* DEC *AdvancePayment(nper, intr, pv, pmt, fv, ad, opt)
*
* ARGUMENT
* int nper, ad, opt;
* DEC *intr, *pv, *pmt, *fv;
*
* DESCRIPTION
* Given five variables involved in compound interest, solves for the
* sixth one. The variables are the number of periods nper, the percentage
* interest rate per period intr, the present value pv, the periodic payment
* pmt, the future value fv, and the number of advanced payments ad,
* while opt tells which variable to solve for.
*
* SIDE EFFECTS
* Changes value of unknown variable.
*
* RETURNS
* In case of success when not solving for nper, the result is returned.
* If solving for nper or if an error occurs, GM_NULL is returned.
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_ARGVAL
*
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *AdvancePayment(nper, intr, pv, pmt, fv, ad, opt)
int nper, ad, opt;
DEC *intr, *pv, *pmt, *fv;
{
DEC *p;
_MacStart(GM_ADVPMT);
if (opt==GM_N || ad>=nper || ad<0) {
_MacErr(GM_ARGVAL);
_MacRet(GM_NULL);
}
p=_CompoundAux(0, &nper, intr, intr, pv, pmt, fv, ad, opt);
_MacRet(p);
}

111
gfm/agmn.asm Executable file
View File

@ -0,0 +1,111 @@
; int _AddUnsArrToUnsArr(src1,src2,dst,n)
;
; ARGUMENT
; unsigned *src1, *src2, *dst;
; unsigned n; /* number of ints to add */
;
; DESCRIPTION
;
; Adds src1 to scr2 giving dst. src1 and scr2 are unchanged.
; src1, src2 and dst point to unsigned arrays.
;
; SIDE EFFECTS
; dst is indeterminate on overflow. Note that although we are using
; unsigned, we return an overflow status from here if the high-order bit
; goes set. Caller can then determine if that is an error in his case.
;
; RETURNS
; Returns GM_SUCCESS if no overflow, otherwise GM_FAILURE.
;
; AUTHOR
; Andy Anderson 13-JAN-1987 13:30
; Copyright (C) 1987-90 Greenleaf Software Inc. All Rights Reserved.
;
; MODIFICATIONS
; Andy Anderson 16-jul-87 80-bit
;
;
include model.h
include prologue.h
include gm.equ
pseg gmath
;
; if large memory model then:
;
; parm1_ = ptr to source 1
; parm3_ = ptr to source 2;
; parm5_ = destination segment ptr
; parm6_ = destination offset ptr
; parm7_ = number of unsigned's to add
;
; for if small model then
; parm1_ = ptr to source1
; parm2_ = ptr to source2
; parm3_ = ptr to destination
; parm4_ = number of unsigned's to add
;
cproc _AddUnsArrToUnsArr,,agmn
if _LDATA
push ds
push es
lds si,parm1_ ; ptr to a
les di,parm3_ ; ptr to b
mov cx,parm7_ ; number of uns's to add
else
mov si,parm1_
mov di,parm2_
mov cx,parm4_
mov dx,parm3_ ; offset to dst
endif
xor bx,bx ; clear flags and offset
addlp:
if _LDATA
mov ax,[si+bx] ; get a digit
adc ax,es:[di+bx]
push ds ; have to exchange for large model
push si
lds si,parm5_ ; destination seg:offset
mov [si+bx],ax ; mov partial product
pop si ; restore ptr to src1
pop ds
pushf ; save overflow flag
inc bx
inc bx ; move to next unsigned
loop addlp
else
mov ax,[si+bx] ; get a digit
adc ax,[di+bx]
xchg dx,si
mov [bx+si],ax
xchg si,dx
pushf ; save overflow flag
inc bx
inc bx ; move to next unsigned
loop addlp
endif
pop bx ; get back last undisturbed flags
test bx,0800h ; mask the overflow bit
jnz overf
mov ax,GM_SUCCESS ; set SUCCESS return for caller
exit:
if _LDATA
mov cx,parm7_
else
mov cx,parm4_
endif
dec cx ; since we've already poped one off
sal cx,1 ; the stack, make byte offset -2
add sp,cx ; clean up stack from pushf's
if _LDATA
pop es
pop ds
endif
cproce
overf:
mov ax,GM_FAILURE
jmp short exit
endps
END

72
gfm/agmn.c Executable file
View File

@ -0,0 +1,72 @@
/* int _AddUnsArrToUnsArr(src1,src2,dst,n)
*
* ARGUMENT
* unsigned *src1, *src2, *dst;
* unsigned n;
*
* DESCRIPTION
* Adds src1 to src2 giving dst. src1 and src2 are unchanged.
* Src1, src2 and dst point to unsigned arrays.
*
* SIDE EFFECTS
*
*
* RETURNS
* GM_SUCCESS if no overflow, otherwise GM_FAILURE.
*
* AUTHOR
* Brugnoli Giugno 1992
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include <math.h>
#include "gm.h"
#include "gmsystem.h"
extern double pow(double, double);
int _AddUnsArrToUnsArr(src1, src2, dst, n)
unsigned SHORT src1[], src2[], dst[];
int n;
{
int i;
unsigned long pdst,maxunsint;
unsigned carry;
carry=0;
#ifdef SH_LIB
maxunsint=1;
for (i=1;i<=BITSPERUI;i++) maxunsint*=2;
maxunsint--;
#else
maxunsint=(unsigned long)pow(2.,(double)BITSPERUI)-1;
#endif
if (n>0)
{
for (i=0;i<n;i++)
{
pdst=carry+(unsigned long)src1[i];
pdst+=(unsigned long)src2[i];
if (pdst>maxunsint)
{
carry=(unsigned)(pdst >> BITSPERUI );
dst[i]=(unsigned SHORT )(pdst & maxunsint );
}
else
{
carry=0;
dst[i]=(unsigned SHORT)pdst;
}
}
if (dst[n-1]>>(BITSPERUI-1))
return(GM_FAILURE);
}
return(GM_SUCCESS);
}

100
gfm/amort.c Executable file
View File

@ -0,0 +1,100 @@
/* void Amortize(payintr,payprin,balance,intr,pv,pmt,begend,time)
*
* ARGUMENT
* DEC *payintr,*payprin,*balance;
* DEC *intr, *pv, *pmt;
* int begend, time;
*
* DESCRIPTION
* For a certain payment of a loan, computes the amount of the payment
* applied towards interest (payintr), the amount of the payment applied
* towards principle (payprin), and the remaining balance (balance). The
* loan is described by its present value (pv), the payment (pmt), the
* interest rate (intr), and whether payments are at the beginning or end
* of the month (begend), while time tells the payment for which the
* calculations should be done. pv should be positive while pmt should be
* negative to obey the sign convention. The output is rounded to two
* decimal places.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* None.
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_ARGVAL
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
void Amortize(payintr,payprin,balance,intr,pv,pmt,begend,time)
DEC *payintr,*payprin,*balance;
DEC *intr, *pv, *pmt;
int begend, time;
{
int i;
DEC dnintr, *nintr=&dnintr, dnpmt, *npmt=&dnpmt;
_MacStart(GM_AMORT);
if (!payintr||!payprin||!balance||!intr||!pv||!pmt) {
_MacErr(GM_NULLPOINTER);
_MacRetV;
}
if (_MacBad(intr) || _MacBad(pv) || _MacBad(pmt)) {
_MacErr(GM_INIT);
_MacRetV;
}
if ((begend!=GM_BEGIN&&begend!=GM_END)||time<0) {
_MacErr(GM_ARGVAL);
_MacRetV;
}
_MacDCopy(nintr, intr);
nintr->dc.id+=2;
_ScaleDec80Bit(npmt,pmt,2);
/* store results for payment '0' */
_MacDZero(payintr);
_MacDZero(payprin);
(void) _ScaleDec80Bit(balance,pv,2);
if (time==0)
_MacRetV;
/* calculate payment 1 results */
if (begend!=GM_BEGIN) {
(void) _MulDec80Bit(payintr, balance, nintr);
(void) _ScaleDec80Bit(payintr, payintr ,2);
if (_MacIsDecN(payintr)^_MacIsDecN(npmt))
_MacDChgs(payintr);
}
(void) _SubDec80Bit(payprin, npmt, payintr);
(void) _SubDec80Bit(balance, balance, payprin);
/* calculate rest of payments */
for (i=2;i<=time;i++) {
(void) _MulDec80Bit(payintr, balance, nintr);
(void) _ScaleDec80Bit(payintr,payintr,2);
if (_MacIsDecN(payintr)^_MacIsDecN(npmt))
_MacDChgs(payintr);
(void) _SubDec80Bit(payprin, npmt, payintr);
(void) _SubDec80Bit(balance, balance, payprin);
}
_MacRetV;
}

112
gfm/amorttbl.c Executable file
View File

@ -0,0 +1,112 @@
/* void AmortizeTable(payintr,payprin,balance,intr,pv,pmt,begend,time)
*
* ARGUMENT
* DEC **payintr, **payprin, **balance;
* DEC *intr, *pv, *pmt;
* int begend, time;
*
* DESCRIPTION
* For several payments of a loan, computes the amount of the payment
* applied towards interest (payintr), the amount of the payment applied
* towards principle (payprin), and the remaining balance (balance). The
* loan is described by its present value (pv), the payment (pmt), the
* interest rate (intr), and whether payments are at the beginning or end
* of the month (begend), while time tells the number of payments for which
* the calculations should be done. pv should be positive while pmt should
* be negative to obey the sign convention. The output is rounded to two
* decimal places. The results are stored in 3 arrays.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* None.
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_ARGVAL
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
void AmortizeTable(payintr,payprin,balance,intr,pv,pmt,begend,time)
DEC **payintr, **payprin, **balance;
DEC *intr, *pv, *pmt;
int begend, time;
{
int i, n1, n2;
DEC dnintr, *nintr=&dnintr, dnpmt, *npmt=&dnpmt;
_MacStart(GM_AMORTTBL);
if (!payintr||!payprin||!balance||!intr||!pv||!pmt) {
_MacErr(GM_NULLPOINTER);
_MacRetV;
}
if (_MacBad(intr) || _MacBad(pv) || _MacBad(pmt)) {
_MacErr(GM_INIT);
_MacRetV;
}
for (i=0;i<=time;i++)
if (!payintr[i]||!payprin[i]||!balance[i]) {
_MacErr(GM_NULLPOINTER);
_MacRetV;
}
if ((begend!=GM_BEGIN&&begend!=GM_END)||time<0) {
_MacErr(GM_ARGVAL);
_MacRetV;
}
_MacDCopy(nintr, intr);
nintr->dc.id+=2;
_ScaleDec80Bit(npmt,pmt,2);
/* store results for payment '0' */
_MacDZero(payintr[0]);
_MacDZero(payprin[0]);
(void) _ScaleDec80Bit(balance[0],pv,2);
if (time==0)
_MacRetV;
/* calculate payment 1 results */
if (begend!=GM_BEGIN) {
(void) _MulDec80Bit(payintr[1], balance[0], nintr);
(void) _ScaleDec80Bit(payintr[1], payintr[1] ,2);
if (_MacIsDecN(payintr[1])^_MacIsDecN(npmt))
_MacDChgs(payintr[1]);
}
else
_MacDZero(payintr[1]);
(void) _SubDec80Bit(payprin[1], npmt, payintr[1]);
(void) _SubDec80Bit(balance[1], balance[0], payprin[1]);
/* calculate rest of payments */
for (i=2;i<=time;i++) {
(void) _MulDec80Bit(payintr[i], balance[i-1], nintr);
(void) _ScaleDec80Bit(payintr[i],payintr[i],2);
/* for some reason, this routine failed when the _MacIsDecN & the ^ are */
/* on the same line as the if */
n1 = _MacIsDecN(payintr[i]);
n2 = _MacIsDecN(npmt);
if (n1 ^ n2)
_MacDChgs(payintr[i]);
(void) _SubDec80Bit(payprin[i], npmt, payintr[i]);
(void) _SubDec80Bit(balance[i], balance[i-1], payprin[i]);
}
_MacRetV;
}

245
gfm/atod.c Executable file
View File

@ -0,0 +1,245 @@
/* DEC *ConvAsciiToDecimal(dst,src1)
*
* ARGUMENT
* dst is a pointer to the destination DEC structure.
* src1 is a ptr to the ascii string to be converted.
*
* DESCRIPTION
* Converts an ascii string to an internal format number
* and puts it into the dst DEC structure. The id is the
* number of digits past the decimal point.
*
* SIDE EFFECTS
* None. The destination structure is indeterminate if
* an overflow of significant digits occured during conversion.
*
* RETURNS
* Returns a pointer to the dest structure unless overflow.
* Otherwise, returns a GM_NULL(a C false). On error, the error
* is in wGMError, unless an error was already there.
* Note that truncation of insignificant digits is not fatal, but
* sets a warning flag for the caller to determine if that is fatal
* for their application.
*
* POSSIBLE ERROR CODES
*
* GM_NULLSTRING
* GM_NAN
* GM_CNVRE
* GM_CNVRW
*
* AUTHOR
* Andy Anderson 13-JAN-1987 14:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
* Mark Nelson 23-Jan-1990
* Modified to handle leading and trailing whitespace, like atoi();
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *ConvAsciiToDecimal( dst, s )
DEC *dst;
char *s;
{
DEC dx, *x=&dx;
int digright;
int sign, k, j, exp, expisn=0, equid, xtra=0;
mbool trwarn=FALSE;
unsigned c10;
register int i, fd;
_MacStart(GM_ATOD);
fd = 0;
sign = 1; /* assume a positive sign */
/* If he hands us a null string, _MacRet error to user */
if (!s) {
_MacErr(GM_NULLSTRING);
_MacRet(GM_NULL);
}
_MacOutVar(dst, GM_NULL);
/* First strip any leading whitespace */
for (; s[fd] == ' ' || s[fd] == '\t' ; fd++ ) ;
/* Then check for an empty string */
if (s[fd] == '\0') {
_MacErr(GM_NULLSTRING);
_MacRet(GM_NULL);
}
/* fix sign */
for (; ((s[fd] == '-') || (s[fd] == '+')); fd++) {
if (s[fd] == '-')
sign = -1;
}
/* Strip leading zeroes from the string */
while ( s[fd] == '0' )
fd++;
/* Search for 'e' or 'E' signifying scientfic notation */
for ( j = fd; ; j++ ) {
if ( s[j] == '\0' )
break;
if ( s[j] == 'e' )
break;
if ( s[j] == 'E' )
break;
if ( s[j] == ' ' )
break;
if ( s[j] == '\t' )
break;
}
/* If there is an exponent, calculate it or _MacRet GM_NAN */
exp = 0;
if ((s[j] == 'e' || s[j] == 'E')) {
k=j+1;
if ((s[k]=='+') || (s[k]=='-')) {
expisn = (s[k]=='-') ? 1 : 0;
k++;
}
do {
if ((s[k]<'0') || (s[k]>'9')) {
_MacErr(GM_NAN);
_MacRet (GM_NULL);
}
exp = 10*exp + s[k] - 0x30;
k++;
} while (s[k] != 0 && s[k] != ' ' && s[k] != '\t' );
if (expisn)
exp = -exp;
}
/* check for bad characters */
for (i=fd; i<j; i++)
if (((s[i] < '0') || (s[i] > '9')) && (s[i] != '.')
&& (s[i] != ',')) {
_MacErr(GM_NAN);
_MacRet (GM_NULL);
}
/* set equal to 0 */
_MacDZero(x);
x->dc.id = 0;
if (fd == j) {
_MacDCopy(dst,x);
_MacRet(dst);
}
/* everything else */
digright = 0;
/* digits before decimal point */
for (i=fd; (i<j ); i++) {
if ((s[i] >= '0') && (s[i] <= '9')) {
c10=s[i] - 0x30;
if (x->dc.sl[3] < 3276L)
(void) _MulUnsArrP10AndAddInt(
x->dc.sl, c10);
else {
if((s[i] >= '5') && wfGMRound)
/* round off */
(void) _IncrementUnsArr(
x->dc.sl);
for (; ((s[i]!='.') && (i<j)); i++)
xtra++;
if (xtra+exp>0) {
_MacErr(GM_CNVRE);
_MacRet(GM_NULL);
}
i=j;
trwarn=TRUE;
break;
}
}
if (s[i] == '.') {
i++;
break;
}
}
/* digits after decimal point */
for (; i<j; i++) {
if ((s[i] >= '0') && (s[i] <= '9')) {
/* after decimal point */
if ((digright-exp<GM_MAXID)&&(x->dc.sl[3]<3276L)) {
/* room for digit */
c10=s[i] - 0x30;
(void) _MulUnsArrP10AndAddInt(
x->dc.sl, c10);
digright++;
}
else {
/* no room for digit */
if((s[i] >= '5') && wfGMRound) {
/* round off */
(void) _IncrementUnsArr(
x->dc.sl);
}
trwarn=TRUE;
break;
}
}
if (s[i] == '.') {
/* two decimal points */
_MacErr(GM_NAN);
_MacRet (GM_NULL);
}
}
/* adjust for exponential */
equid = digright-xtra-exp;
if ((equid>=GM_MINID) && (equid<=GM_MAXID))
x->ls.lid=equid;
if (equid>GM_MAXID) {
x->ls.lid=GM_MAXID;
trwarn=TRUE;
if (!_MacIsDecZ(x)) {
if (wfGMRound)
_DivUnsArrByPwrOf10( x->dc.sl,
5, equid-GM_MAXID);
else
_DivUnsArrByPwrOf10( x->dc.sl,
5, equid-GM_MAXID);
if (_MacIsDecZ(x)) {
_MacErr(GM_CNVRE);
}
}
}
if (equid<GM_MINID) {
k=_MulUnsArrByPwrOf10( x->dc.sl, GM_MINID-equid, 5);
if ((k!=GM_SUCCESS) || (x->dc.msd!=0)
|| (x->dc.sl[3] > 32767L)) {
_MacErr(GM_CNVRE);
_MacRet(GM_NULL);
}
x->dc.id=GM_MINID;
}
/* adjust for sign */
if (sign == -1)
_MacDChgs(x);
_MacDCopy(dst, x);
if (trwarn)
_MacErr(GM_CNVRW);
_MacRet(dst);
}

252
gfm/atodr.c Executable file
View File

@ -0,0 +1,252 @@
/* DEC *ConvAsciiToDecimalRound(dst,src1,nid)
*
* ARGUMENT
* dst is a pointer to the destination DEC structure.
* src1 is a ptr to the ascii string to be converted.
*
* DESCRIPTION
* Converts an ascii string to an internal format number
* and puts it into the dst DEC structure. The number is rounded
* to nid decimal places.
*
* SIDE EFFECTS
* None. The destination structure is indeterminate if
* an overflow of significant digits occured during conversion.
*
* RETURNS
* Returns a pointer to the dest structure unless overflow.
* Otherwise, returns a GM_NULL(a C false). On error, the error
* is in wGMError, unless an error was already there.
* Note that truncation of insignificant digits is not fatal, but
* sets a warning flag for the caller to determine if that is fatal
* for their application.
*
* POSSIBLE ERROR CODES
*
* GM_NULLSTRING
* GM_NAN
* GM_CNVRE
* GM_CNVRW
* GM_INVALIDID
*
* AUTHOR
* Andy Anderson 13-JAN-1987 14:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
* Mark Nelson 23-Jan-1990
* Modified to handle leading and trailing whitespace, like atoi();
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *ConvAsciiToDecimalRound(dst, s, nid )
DEC *dst;
char *s;
int nid;
{
DEC dx, *x=&dx;
int digright;
int sign, k, j, exp, expisn=0, equid, xtra=0;
mbool trwarn=FALSE;
unsigned c10;
register int i, fd;
_MacStart(GM_ATODR);
fd = 0;
sign = 1; /* assume a positive sign */
/* If he hands us a null string, _MacRet error to user */
if (!s) {
_MacErr(GM_NULLSTRING);
_MacRet(GM_NULL); }
/* check for valid nid */
if ((nid < GM_MINID) || (nid > GM_MAXID)) {
_MacErr(GM_INVALIDID);
_MacRet(GM_NULL);
}
/* handle null pointers */
if (!dst) {
_MacErr(GM_NULLPOINTER);
_MacRet(GM_NULL);
}
/* First strip any leading whitespace */
for (; s[fd] == ' ' || s[fd] == '\t' ; fd++ ) ;
/* Then check for an empty string */
if (s[fd] == '\0') {
_MacErr(GM_NULLSTRING);
_MacRet(GM_NULL);
}
/* fix sign */
for (; ((s[fd] == '-') || (s[fd] == '+')); fd++) {
if (s[fd] == '-')
sign = -1;
}
/* Strip leading zeroes from the string */
while ( s[fd] == '0' )
fd++;
/* Search for 'e' or 'E' signifying scientfic notation */
for ( j = fd; ; j++ ) {
if ( s[j] == '\0' )
break;
if ( s[j] == 'e' )
break;
if ( s[j] == 'E' )
break;
if ( s[j] == ' ' )
break;
if ( s[j] == '\t' )
break;
}
/* If there is an exponent, calculate it or _MacRet GM_NAN */
exp = 0;
if ((s[j] == 'e' || s[j] == 'E')) {
k=j+1;
if ((s[k]=='+') || (s[k]=='-')) {
expisn = (s[k]=='-') ? 1 : 0;
k++;
}
do {
if ((s[k]<'0') || (s[k]>'9')) {
_MacErr(GM_NAN);
_MacRet (GM_NULL);
}
exp = 10*exp + s[k] - 0x30;
k++;
} while (s[k] != 0 && s[k] != ' ' && s[k] != '\t' );
if (expisn)
exp = -exp;
}
/* check for bad characters */
for (i=fd; i<j; i++)
if (((s[i] < '0') || (s[i] > '9')) && (s[i] != '.')
&& (s[i] != ',')) {
_MacErr(GM_NAN);
_MacRet (GM_NULL);
}
/* set equal to 0 */
_MacDZero(x);
x->dc.id = 0;
if (fd == j) {
_MacDCopy(dst, x);
_MacRet(dst);
}
/* everything else */
digright = 0;
/* digits before decimal point */
for (i=fd; (i<j ); i++) {
if ((s[i] >= '0') && (s[i] <= '9')) {
c10=s[i] - 0x30;
if (x->dc.sl[3] < 3276L)
(void) _MulUnsArrP10AndAddInt(
x->dc.sl, c10);
else {
if((s[i] >= '5') && wfGMRound)
/* round off */
(void) _IncrementUnsArr(
x->dc.sl);
for (; ((s[i]!='.') && (i<j)); i++)
xtra++;
if (xtra+exp>0) {
_MacErr(GM_CNVRE);
_MacRet(GM_NULL);
}
i=j;
trwarn=TRUE;
break;
}
}
if (s[i] == '.') {
i++;
break;
}
}
/* digits after decimal point */
for (; i<j; i++) {
if ((s[i] >= '0') && (s[i] <= '9')) {
/* after decimal point */
if ((digright-exp<nid)&&(x->dc.sl[3]<3276L)) {
/* room for digit */
c10=s[i] - 0x30;
(void) _MulUnsArrP10AndAddInt(
x->dc.sl, c10);
digright++;
}
else {
/* no room for digit */
if((s[i] >= '5') && wfGMRound) {
/* round off */
(void) _IncrementUnsArr(
x->dc.sl);
}
trwarn = TRUE;
break;
}
}
if (s[i] == '.') {
/* two decimal points */
_MacErr(GM_NAN);
_MacRet (GM_NULL);
}
}
/* adjust for exponential */
equid = digright-xtra-exp;
x->ls.lid=nid;
if (equid>nid) {
trwarn=TRUE;
if (!_MacIsDecZ(x)) {
if (wfGMRound)
_DivUnsArrByPwrOf10( x->dc.sl,
5, equid-nid);
else
_DivUnsArrByPwrOf10Trunc( x->dc.sl,
5, equid-nid);
if (_MacIsDecZ(x)) {
_MacErr(GM_CNVRE);
}
}
}
if (equid<nid) {
k=_MulUnsArrByPwrOf10( x->dc.sl, nid-equid, 5);
if ((k!=GM_SUCCESS) || (x->dc.msd!=0)
|| (x->dc.sl[3] > 32767L)) {
_MacErr(GM_CNVRE);
_MacRet(GM_NULL);
}
}
/* adjust for sign */
if (sign == -1)
_MacDChgs(x);
_MacDCopy(dst, x);
if (trwarn)
_MacErr(GM_CNVRW);
_MacRet(dst);
}

131
gfm/bondprc.c Executable file
View File

@ -0,0 +1,131 @@
/* DEC *BondPrice(price, acc,yield, coupon, ppy, mop, dap, yrp, mom, dam, yrm)
*
* ARGUMENT
* DEC *price;
* DEC *yield;
* DEC *coupon;
* int ppy;
* int mop, dap, yrp;
* int mom, dam, yrm;
*
* DESCRIPTION
* Calculate the price of a bond given the desired yield, coupon rate
* for receiving interest on a bond, number of payments per year, and the
* puchase and maturity dates.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* price if successful, otherwise GM_NULL
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_INIT
* GM_ARGVAL
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
* Mark Nelson
* Fixed bond pricing to accurately convert effective to nominal before
* making calculations.
*
*/
#include <stdio.h>
#include "gmsystem.h"
DEC *BondPrice(price,acc,yield,coupon, ppy, mop, dap, yrp, mom, dam, yrm)
DEC *price, *yield, *coupon, *acc;
int ppy, mop, dap, yrp, mom, dam, yrm;
{
DEC dtemp, *temp=&dtemp, dtemp2, *temp2=&dtemp2;
DEC dnper, *nper=&dnper, dpmt, *pmt=&dpmt;
DEC dnyield, *nyield=&dnyield, dfvopi, *fvopi=&dfvopi;
DEC ddsc, *dsc=&ddsc, ddcs, *dcs=&ddcs;
DEC dopi, *opi=&dopi, dopinm1, *opinm1=&dopinm1;
int ndays, npay;
_MacStart(GM_BONDPRC);
_MacInVarD(yield);
_MacInVarD(coupon);
_MacOutVarD(price);
if (ppy<1||ppy>12||CompareDecimal(yield,&decMinusHundred)<=0) {
_MacErr(GM_ARGVAL);
_MacRet(GM_NULL);
}
/* calculate # of periods, including partial period */
ndays = DaysBetweenDates360(mom, dam, yrm, mop, dap, yrp);
if (ndays < 0) {
if (ndays!=GM_ARGVAL&&ndays!=GM_OVERFLOW)
_MacErr(GM_ARGVAL);
_MacRet(GM_NULL);
}
/* calculate number of interest payments remaining */
(void) ConvLongToDecimal(temp, (long)ppy * (long) ndays);
(void) ConvLongToDecimal(temp2, 360L);
(void) _DivDec80Bit(nper, temp, temp2);
(void) _TruncateDec80Bit(temp, nper, 0);
npay=temp->dc.sl[0]+1; /* int number of interest payments */
(void) _SubDec80Bit(dsc, nper, temp); /* days purchase - next int */
(void) _SubDec80Bit(dcs, &decOne, dsc); /* days last int - purchass */
if (_MacIsDecZ(dsc))
_MacDZero(dcs);
/* calculate coupon rate per period */
(void) ConvLongToDecimal(temp2, (long)ppy);
(void) _DivDec80Bit(pmt, coupon, temp2);
/* calculate yield per period */
_MacDCopy( nyield, yield );
nyield->dc.id += 2;
_AddDec80Bit( nyield, nyield, &decOne );
_LnDec80Bit( nyield, nyield);
_DivDec80Bit( nyield, nyield, temp2 );
_ExpDec80Bit( nyield, nyield );
_SubDec80Bit( nyield, nyield, &decOne );
if (CompareDecimal(nper, &decOne)<=0) { /* < 1 period to maturity */
(void) _AddDec80Bit(temp, &decHundred, pmt);
(void) _MulDec80Bit(temp2, dsc, nyield);
(void) _AddDec80Bit(temp2, temp2, &decOne);
(void) _DivDec80Bit(price, temp, temp2);
}
else { /* > 1 period to maturity */
(void) _AddDec80Bit(opi, nyield, &decOne);
(void) _IntPwrDec80Bit(opinm1, opi, -(npay-1));
(void) _MulDec80Bit(fvopi, &decHundred, opinm1);
if (_MacIsDecZ(nyield))
ConvLongToDecimal(temp, (long) npay);
else {
(void) _SubDec80Bit(temp, opi, opinm1);
(void) _DivDec80Bit(temp, temp, nyield);
}
(void) _MulDec80Bit(temp, temp, pmt);
(void) _AddDec80Bit(temp, temp, fvopi);
_MacDChgs(dsc);
(void) PowerDecimal(temp2, opi, dsc);
(void) _MulDec80Bit(price, temp, temp2);
}
(void) _MulDec80Bit(acc, pmt, dcs);
(void) _Sq5UnsTo4Uns(acc);
if (_MacIsDecZ(dsc))
(void) _SubDec80Bit(price, price, pmt);
else
(void) _SubDec80Bit(price, price, acc);
(void) _Sq5UnsTo4Uns(price);
_MacRet(price);
}

122
gfm/bondyld.c Executable file
View File

@ -0,0 +1,122 @@
/* DEC *BondYield(yield, price, coupon, ppy, mop, dap, yrp, mom, dam, yrm)
*
* ARGUMENT
* DEC *price;
* DEC *yield;
* DEC *coupon;
* int ppy;
* int mop, dap, yrp;
* int mom, dam, yrm;
*
* DESCRIPTION
* Calculate the yield of a bond given the price, coupon rate
* for receiving interest on a bond, number of payments per year, and the
* puchase and maturity dates.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* yield if successful, otherwise GM_NULL
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_INIT
* GM_ARGVAL
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
* Mark Nelson
* Added one line to convert nominal interest rate to effective.
*
*/
#include <stdio.h>
#include "gmsystem.h"
DEC *BondYield(yield, price, coupon, ppy, mop, dap, yrp, mom, dam, yrm)
DEC *price, *yield, *coupon;
int ppy, mop, dap, yrp, mom, dam, yrm;
{
DEC dtemp, *temp=&dtemp, dtemp2, *temp2=&dtemp2;
DEC dnper, *nper=&dnper, dpmt, *pmt=&dpmt;
DEC dpv, *pv=&dpv, dfv, *fv=&dfv, *p;
DEC ddsc, *dsc=&ddsc, ddcs, *dcs=&ddcs;
int ndays, npay;
_MacStart(GM_BONDYLD);
_MacInVarD(coupon);
_MacInVarD(price);
_MacOutVarD(yield);
if (ppy<1||ppy>12) {
_MacErr(GM_ARGVAL);
_MacRet(GM_NULL);
}
/* calculate # of periods, including partial period */
ndays = DaysBetweenDates360(mom, dam, yrm, mop, dap, yrp);
if (ndays < 0) {
if (ndays!=GM_ARGVAL&&ndays!=GM_OVERFLOW)
_MacErr(GM_ARGVAL);
_MacRet(GM_NULL);
}
/* calculate number of interest payments remaining */
(void) ConvLongToDecimal(temp, (long)ppy * (long) ndays);
(void) ConvLongToDecimal(temp2, 360L);
(void) _DivDec80Bit(nper, temp, temp2);
(void) _TruncateDec80Bit(temp, nper, 0);
npay=temp->dc.sl[0];
(void) _SubDec80Bit(dsc, nper, temp); /* days purchase - next int */
(void) _SubDec80Bit(dcs, &decOne, dsc); /* days last int - purchass */
/* calculate coupon rate per period */
(void) ConvLongToDecimal(temp2, (long)ppy);
(void) _DivDec80Bit(pmt, coupon, temp2);
(void) _AddDec80Bit(fv, &decHundred, pmt);
(void) _MulDec80Bit(temp, pmt, dcs);
(void) _AddDec80Bit(pv, price, temp);
if (CompareDecimal(nper, &decOne)<=0) { /* < 1 period to maturity */
_DivDec80Bit(temp, fv, pv);
_SubDec80Bit(temp, temp, &decOne);
_DivDec80Bit(yield, temp, dsc);
_MulDec80Bit(yield, yield, &decHundred);
_ScaleDec80Bit(yield, yield, wIntrPrec);
}
else { /* > 1 period to maturity */
_MacDChgs(pv);
p = _InterestAux(3, npay, dsc, yield, pv, pmt, fv, GM_BEGIN);
if (!p)
_MacRet(GM_NULL);
}
/*
* At this point, yield contains the nominal interest rate for the bond.
* This needs to be converted to the effective interest rate. Rather than
* call the NominalToEffective routine, I import most of the code.
*/
yield->dc.id += 2;
_AddDec80Bit( yield, yield, &decOne );
if (_IntPwrDec80Bit( yield, yield, ppy ) != GM_SUCCESS ) {
_MacErr( GM_ARGVAL );
_MacRet( GM_NULL );
}
_SubDec80Bit( yield, yield, &decOne );
if (yield->dc.id >= GM_MINID+2)
yield->dc.id -= 2;
else
(void) _MulUnsArrByPwrOf10(yield->dc.sl, 5, 2);
if (_Sq5UnsTo4Uns(yield)!=GM_SUCCESS) {
_MacErr(GM_ARGVAL);
_MacRet(GM_NULL);
}
_MacRet(yield);
}

5
gfm/build Executable file
View File

@ -0,0 +1,5 @@
CCOMP=msc
LIB1=/lib/Llibgfma.a
LIB2=/lib/Llibgfmb.a
export CCOMP LIB1 LIB2
make

6
gfm/build3 Executable file
View File

@ -0,0 +1,6 @@
CCOMP=msc3
LIB1=/lib/386/Slibgfma.a
LIB2=/lib/386/Slibgfmb.a
FLAGS=-c
export CCOMP LIB1 LIB2 FLAGS
make -f makefile3

6
gfm/buildd3 Executable file
View File

@ -0,0 +1,6 @@
CCOMP=msc3
LIB1=/lib/386/Slibgfmad.a
LIB2=/lib/386/Slibgfmbd.a
FLAGS=-d
export CCOMP LIB1 LIB2 FLAGS
make -f makefile3

5
gfm/builddos Executable file
View File

@ -0,0 +1,5 @@
CCOMP=mscdos
LIB1=/usr/lib/dos/Ldlibgfma.a
LIB2=/usr/lib/dos/Ldlibgfmb.a
export CCOMP LIB1 LIB2
make

1
gfm/buildsh Executable file
View File

@ -0,0 +1 @@
make -f makelsh

51
gfm/comp.c Executable file
View File

@ -0,0 +1,51 @@
/* DEC *CompoundInterest(nper, intr, pv, pmt, fv, begend, opt)
*
* ARGUMENT
* int *nper, begend, opt;
* DEC *intr, *pv, *pmt, *fv;
*
* DESCRIPTION
* Given four variables involved in compound interest, solves for the
* fifth one. The variables are the number of periods nper, the percentage
* interest rate per period intr, the present value pv, the periodic payment
* pmt, and the future value fv. begend specifies whether payments take
* place at the beginning or the end of each month, while opt tells which
* variable to solve for.
*
* SIDE EFFECTS
* Changes value of unknown variable.
*
* RETURNS
* In case of success when not solving for nper, the result is returned.
* If solving for nper or if an error occurs, GM_NULL is returned.
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_ARGVAL
*
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *CompoundInterest(nper, intr, pv, pmt, fv, begend, opt)
int *nper, begend, opt;
DEC *intr, *pv, *pmt, *fv;
{
DEC *p;
_MacStart(GM_COMP);
p=_CompoundAux(1, nper, intr, intr, pv, pmt, fv, begend, opt);
_MacRet(p);
}

384
gfm/compaux.c Executable file
View File

@ -0,0 +1,384 @@
/* DEC *_CompoundAux(fun, nperi, nperd, intr, pv, pmt, fv, begend, opt)
*
* ARGUMENT
* int fun, *nperi, begend, opt;
* DEC *nperd, *intr, *pv, *pmt, *fv;
*
* DESCRIPTION
* Given four variables involved in compound interest, solves for the
* fifth one. The variables are the number of periods nper, the percentage
* interest rate per period intr, the present value pv, the periodic payment
* pmt, and the future value fv. begend specifies whether payments take
* place at the beginning or the end of each month, while opt tells which
* variable to solve for.
* This auxillary function does the work of CompoundInterest,
* CompoundInterestSimple, CompoundInterestCompound,
* and AdvancePayment.
*
* SIDE EFFECTS
* Changes value of unknown variable.
*
* RETURNS
* In case of success when not solving for nper, the result is returned.
* If solving for nper or if an error occurs, GM_NULL is returned.
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_ARGVAL
*
*
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* ALGORITHM
* Solve the following formula for the unknown variable:
* 0=pv*alpha + (1+intr*begend)*pmt*[1-(1+intr)^-int(nper)]/intr +
* fv*(1+intr)^-int(nper)
* where alpha=1 for no odd period,
* alpha=1+intr*frac(nper) for an odd period with simple interest
* alpha=(1+intr)^frac(nper) for an odd period with compound interest
*
* If intr==0, the function solves
* 0 = pv + nper * pmt + fv
* If nper==0, the function solves
* 0 = pv * alpha + fv
*
* The equation can be solved in closed form for any variable except intr,
* which requires numerical methods.
* The variables used by this routine have the following meanings:
* fun: 1 if called by ComoundInterest, 2 if by CompoundInterestSimple,
* 3 if by CompoundInterestCompound, and 0 if by AdvancePayment
* nperi: integer number of periods if fun==1
* nperd: DEC number of periods if fun==2 or fun==3
* intr: interest rate per period
* pv: present value
* pmt: period payment
* fv: future value (balloon payment)
* begend: GM_BEGIN if payments at beginning of period, GM_END if at end
* (or if fun==0, number of advanced payments ad)
* opt: variable to solve for: GM_N, GM_PV, GM_INTR, GM_FV, GM_PMT
*
* opi: 1 + intr
* intper: integer part of nper
* fractper: fractional part of nper (if fun==2 or fun==3)
* opitmn: (1 + intr) ^ -intper
* mess: (1 + begend)[1 - (1 + intr) ^ -intper]/intr
* alpha: 1 + intr * fractper if fun==2, (1 + intr) ^ fractper if fun==3
* pva: pv * alpha
* fvopi: fv * opitmn
* pmtm: pmt * mess
* temp, temp2: temporary DEC's
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *_CompoundAux(fun, nperi, nperd, intr, pv, pmt, fv, begend, opt)
int fun, *nperi, begend, opt;
DEC *nperd, *intr, *pv, *pmt, *fv;
{
int intper, ad;
DEC dopi, *opi=&dopi, dfractper, *fractper=&dfractper;
DEC dmess, *mess=&dmess, dalpha, *alpha=&dalpha;
DEC dpva, *pva=&dpva, dfvopi, *fvopi=&dfvopi;
DEC dpmtm, *pmtm=&dpmtm, dopitmn, *opitmn=&dopitmn;
DEC dtemp, *temp=&dtemp, dtemp2, *temp2=&dtemp2;
DEC dnintr, *nintr=&dnintr;
DEC ddad, *dad=&ddad, dopitmna, *opitmna=&dopitmna;
if (!intr||!pv||!pmt||!fv||!nperd) {
_MacErr(GM_NULLPOINTER);
return(GM_NULL);
}
if ((opt!=GM_I && _MacBad(intr)) || (opt!=GM_PV && _MacBad(pv)) ||
(opt!=GM_PMT && _MacBad(pmt)) || (opt!=GM_FV && _MacBad(fv))) {
_MacErr(GM_INIT);
return(GM_NULL);
}
if ((begend!=GM_BEGIN&&begend!=GM_END&&fun!=0)||
(opt!=GM_N&&opt!=GM_I&&opt!=GM_PV&&opt!=GM_PMT&&opt!=GM_FV)||
(opt!=GM_I&&CompareDecimal(intr,&decMinusHundred)!=1)) {
_MacErr(GM_ARGVAL);
return(GM_NULL);
}
ad = begend;
if (opt!=GM_N) {
/* determine integer & fractional parts of nper, if in range */
if (fun<=1) {
if (*nperi<0) {
_MacErr(GM_ARGVAL);
return(GM_NULL);
}
intper=*nperi;
}
else {
if (_MacIsDecN(nperd)||
(CompareDecimal(nperd,&decMaxTime)==1)) {
_MacErr(GM_ARGVAL);
return(GM_NULL);
}
(void) _TruncateDec80Bit(temp, nperd, 0);
intper=temp->dc.sl[0];
(void) _SubDec80Bit(fractper, nperd, temp);
}
}
if (opt==GM_I) {
opi=_InterestAux(fun, intper, fractper,
intr, pv, pmt, fv, begend);
return(opi);
}
_MacDCopy(nintr, intr);
nintr->dc.id+=2;
/* opi = 1+i */
(void) _AddDec80Bit(opi, nintr, &decOne);
if (opt!=GM_N) {
/* handle zero interest */
if (_MacIsDecZ(intr)) {
(void) ConvLongToDecimal(temp2, (long) intper);
if (opt==GM_PV) {
(void) _MulDec80Bit(temp, temp2, pmt);
(void) _AddDec80Bit(temp, temp, fv);
_MacDChgs(temp);
(void) _ScaleDec80Bit(pv, temp, 2);
return(pv);
}
if (opt==GM_FV) {
(void) _MulDec80Bit(temp, temp2, pmt);
(void) _AddDec80Bit(temp, temp, pv);
_MacDChgs(temp);
(void) _ScaleDec80Bit(fv, temp, 2);
return(fv);
}
if (opt==GM_PMT) {
if (intper==0) {
_MacErr(GM_ARGVAL);
return(GM_NULL);
}
(void) _AddDec80Bit(temp, pv, fv);
_MacDChgs(temp);
(void) _DivRndDec80Bit(pmt, temp, temp2, 2);
return(pmt);
}
}
/* calculate alpha */
if (fun==2) {
(void) _MulDec80Bit(temp, nintr, fractper);
(void) _AddDec80Bit(alpha, temp, &decOne);
}
if (fun==3) {
(void) _LnDec80Bit(temp, opi);
(void) _MulDec80Bit(temp, temp, fractper);
(void) _ExpDec80Bit(alpha, temp);
}
/* handle zero nper */
if (intper==0) {
if (opt==GM_PMT) {
_MacErr(GM_ARGVAL);
return(GM_NULL);
}
if (opt==GM_PV) {
if (fun<=1)
(void) _ScaleDec80Bit(pv, fv, 2);
else
(void) _DivRndDec80Bit(
pv, fv, alpha, 2);
_MacDChgs(pv);
return(pv);
}
if (opt==GM_FV) {
if (fun<=1)
(void) _ScaleDec80Bit(fv, pv, 2);
else {
(void) _MulDec80Bit(fv, pv, alpha);
(void) _ScaleDec80Bit(fv, fv, 2);
}
_MacDChgs(fv);
return(fv);
}
}
/* calcuate (1+i)^-n and (1+iS)[1-(1+i)^-n]/i */
(void) _IntPwrDec80Bit(opitmn, opi, -intper);
(void) _SubDec80Bit(temp, &decOne, opitmn);
/* Advance payment needs (1+i)^-(n-a) */
if (fun==0) {
(void) _IntPwrDec80Bit(opitmna, opi, -(intper-ad));
(void) _SubDec80Bit(temp, &decOne, opitmna);
(void) ConvLongToDecimal(dad, (long) ad);
}
else
(void) _SubDec80Bit(temp, &decOne, opitmn);
(void) _DivDec80Bit(mess, temp, nintr);
if (begend==GM_BEGIN && fun!=0)
(void) _MulDec80Bit(mess, mess, opi);
if ((opt==GM_PMT||opt==GM_FV)) {
if (fun>1)
(void) _MulDec80Bit(pva, pv, alpha);
if (fun<=1)
_MacDCopy(pva, pv);
}
/* calculate FV*(1+i)^-n */
if (opt==GM_PV||opt==GM_PMT)
(void) _MulDec80Bit(fvopi, fv, opitmn);
if (opt==GM_PV||opt==GM_FV)
(void) _MulDec80Bit(pmtm, pmt, mess);
if (opt==GM_PV) {
(void) _AddDec80Bit(temp, pmtm, fvopi);
_MacDChgs(temp);
if (fun>1)
(void) _DivRndDec80Bit(pv, temp, alpha, 2);
if (fun==1)
(void) _ScaleDec80Bit(pv, temp, 2);
if (fun==0) {
(void) _MulDec80Bit(temp2, dad, pmt);
(void) _SubDec80Bit(temp, temp, temp2);
(void) _ScaleDec80Bit(pv, temp, 2);
}
return(pv);
}
if (opt==GM_PMT) {
(void) _AddDec80Bit(temp, pva, fvopi);
_MacDChgs(temp);
if (fun==0)
(void) _AddDec80Bit(mess, mess, dad);
(void) _DivRndDec80Bit(pmt, temp, mess, 2);
return(pmt);
}
if (opt==GM_FV) {
if (fun==0) {
(void) _MulDec80Bit(temp, pmt, dad);
(void) _AddDec80Bit(pva, pv, temp);
}
(void) _AddDec80Bit(temp, pva, pmtm);
_MacDChgs(temp);
(void) _DivRndDec80Bit(fv, temp, opitmn, 2);
return(fv);
}
}
/* opt==GM_N */
/* handle zero interest */
if (_MacIsDecZ(intr)) {
if (_MacIsDecZ(pmt)) {
_MacErr(GM_ARGVAL);
return(GM_NULL);
}
(void) _AddDec80Bit(temp, pv, fv);
_MacDChgs(temp);
(void) _DivTrnDec80Bit(temp2, temp, pmt, 0);
/* check for exact division => don't increment */
(void) _MulDec80Bit(mess, temp2, pmt);
if (CompareDecimal(temp,mess)!=0)
(void) _AddDec80Bit(temp2, temp2, &decOne);
if (_MacIsDecN(temp2)||CompareDecimal(temp2,&decMaxTime)==1) {
_MacErr(GM_ARGVAL);
return(GM_NULL);
}
if (fun==1) {
*nperi=temp2->dc.sl[0];
return(GM_NULL);
}
else {
_MacDCopy(nperd, temp2);
return(nperd);
}
}
/* first solve for integer part of period */
(void) _DivDec80Bit(temp, pmt, nintr);
if (begend==GM_BEGIN)
(void) _MulDec80Bit(temp, temp, opi);
_MacDCopy(temp2, temp);
(void) _AddDec80Bit(temp, temp, pv);
(void) _SubDec80Bit(temp2, temp2, fv);
if (_MacIsDecZ(temp)||_MacIsDecZ(temp2)) {
_MacErr(GM_ARGVAL);
return(GM_NULL);
}
(void) _DivDec80Bit(temp, temp2, temp);
if (!_MacIsDecP(temp)) {
_MacErr(GM_ARGVAL);
return(GM_NULL);
}
(void) _LnDec80Bit(temp, temp);
(void) _LnDec80Bit(temp2, opi);
(void) _DivTrnDec80Bit(temp, temp, temp2, 0);
if (_MacIsDecN(temp)||(CompareDecimal(temp,&decMaxTime)==1)) {
_MacErr(GM_ARGVAL);
return(GM_NULL);
}
intper=temp->dc.sl[0]+1;
if (intper==1)
intper--;
/* the +1 rounding assumes the ratio of logarithms is not an integer */
if (fun==1) {
*nperi=intper; /* always round up */
return(GM_NULL);
}
/* fun > 1 */
(void) ConvLongToDecimal(nperd, (long) intper);
/* zero pv makes fractional period irrelevant */
if (_MacIsDecZ(pv))
return(nperd);
/* now solve for fractional part & add to integer part */
(void) _IntPwrDec80Bit(opitmn, opi, -intper);
(void) _SubDec80Bit(temp, &decOne, opitmn);
(void) _DivDec80Bit(mess, temp, nintr);
if (begend==GM_BEGIN)
(void) _MulDec80Bit(mess, mess, opi);
(void) _MulDec80Bit(pmtm, pmt, mess);
(void) _MulDec80Bit(fvopi, fv, opitmn);
(void) _AddDec80Bit(temp, pmtm, fvopi);
_MacDChgs(temp);
(void) _DivDec80Bit(alpha, temp, pv);
if (fun==2) {
(void) _SubDec80Bit(temp, alpha, &decOne);
(void) _DivDec80Bit(fractper, temp, nintr);
(void) _AddDec80Bit(nperd, nperd, fractper);
(void) _Sq5UnsTo4Uns(nperd);
}
if (fun==3) {
if (!_MacIsDecP(alpha))
return(nperd);
(void) _LnDec80Bit(temp, alpha);
(void) _LnDec80Bit(temp2, opi);
(void) _DivDec80Bit(fractper, temp, temp2);
(void) _AddDec80Bit(nperd, nperd, fractper);
(void) _Sq5UnsTo4Uns(nperd);
}
return(nperd);
}

52
gfm/compcomp.c Executable file
View File

@ -0,0 +1,52 @@
/* DEC *CompoundInterestCompound(nper, intr, pv, pmt, fv, begend, opt)
*
* ARGUMENT
* int begend, opt;
* DEC *nper, *intr, *pv, *pmt, *fv;
*
* DESCRIPTION
* Given four variables involved in compound interest, solves for the
* fifth one. The variables are the number of periods nper, the percentage
* interest rate per period intr, the present value pv, the periodic payment
* pmt, and the future value fv. begend specifies whether payments take
* place at the beginning or the end of each month, while opt tells which
* variable to solve for.
* This function allows for a partial first period during which compound
* interest is computed.
*
* SIDE EFFECTS
* Changes value of unknown variable.
*
* RETURNS
* In case of success, the result is returned.
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_ARGVAL
*
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *CompoundInterestCompound(nper, intr, pv, pmt, fv, begend, opt)
int begend, opt;
DEC *nper, *intr, *pv, *pmt, *fv;
{
DEC *p;
_MacStart(GM_COMPCOMP);
p=_CompoundAux(3, &opt, nper, intr, pv, pmt, fv, begend, opt);
_MacRet(p);
}

52
gfm/compsimp.c Executable file
View File

@ -0,0 +1,52 @@
/* DEC *CompoundInterestSimple(nper, intr, pv, pmt, fv, begend, opt)
*
* ARGUMENT
* int begend, opt;
* DEC *nper, *intr, *pv, *pmt, *fv;
*
* DESCRIPTION
* Given four variables involved in compound interest, solves for the
* fifth one. The variables are the number of periods nper, the percentage
* interest rate per period intr, the present value pv, the periodic payment
* pmt, and the future value fv. begend specifies whether payments take
* place at the beginning or the end of each month, while opt tells which
* variable to solve for.
* This function allows for a partial first period during which simple
* interest is computed.
*
* SIDE EFFECTS
* Changes value of unknown variable.
*
* RETURNS
* In case of success, the result is returned.
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_ARGVAL
*
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *CompoundInterestSimple(nper, intr, pv, pmt, fv, begend, opt)
int begend, opt;
DEC *nper, *intr, *pv, *pmt, *fv;
{
DEC *p;
_MacStart(GM_COMPSIMP);
p=_CompoundAux(2, &opt, nper, intr, pv, pmt, fv, begend, opt);
_MacRet(p);
}

53
gfm/d10by5.c Executable file
View File

@ -0,0 +1,53 @@
/* void _DivUns10ArrByUns5Arr(c, a, b)
*
* ARGUMENT
* unsigned c[], a[], b[];
*
* DESCRIPTION
* Divides a 10-word by a 5-word, giving a 5-word, setting c = a / b.
* This functions assumes that b > 0 and a / b < 2^79, and will break if
* those conditions are not true. The result is always rounded off.
* It calls dmbyn and ginc.
*
* SIDE EFFECTS
* a and b may be destroyed, but they are not needed later on.
*
* RETURNS
* None.
*
* AUTHOR
* Jared Levy Aug 5, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
void _DivUns10ArrByUns5Arr(c, a, b)
unsigned SHORT c[], a[], b[];
{
register int m, n;
n = 4;
while (b[n] == 0 && n>0)
n--;
if (n == 0) { /* dividing by a 1 digit number */
_DivUnsArrByUnsRound(a, b[0], 6);
for (m=0; m<5; m++)
c[m]=a[m];
}
else {
/* dividing by a multi digit number */
m = 9;
while (a[m] == 0 && m>0)
m--;
_DivUnsArrByUnsArr(c, a, m+1, b, n+1, 1);
}
}

53
gfm/d10by5t.c Executable file
View File

@ -0,0 +1,53 @@
/* void _DivUns10ArrByUns5ArrTrn(c, a, b)
*
* ARGUMENT
* unsigned c[], a[], b[];
*
* DESCRIPTION
* Divides a 10-word by a 5-word, giving a 5-word, setting c = a / b.
* This functions assumes that b > 0 and a / b < 2^79, and will break if
* those conditions are not true. The result is always truncated.
* It calls dmbyn.
*
* SIDE EFFECTS
* a and b may be destroyed, but they are not needed later on.
*
* RETURNS
* None.
*
* AUTHOR
* Jared Levy Aug 5, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
void _DivUns10ArrByUns5ArrTrn(c, a, b)
unsigned SHORT c[], a[], b[];
{
register int m, n;
n = 4;
while (b[n] == 0 && n>0)
n--;
if (n == 0) { /* dividing by a 1 digit number */
(void) _DivUnsArrByUns(a, b[0], 6);
for (m=0; m<5; m++)
c[m]=a[m];
}
else {
/* dividing by a multi digit number */
m = 9;
while (a[m] == 0 && m>0)
m--;
_DivUnsArrByUnsArr(c, a, m+1, b, n+1, 0);
}
}

47
gfm/dabs.c Executable file
View File

@ -0,0 +1,47 @@
/* DEC *AbsoluteDecimal(pDst,pSrc1);
*
* ARGUMENT
* DEC *pDst,*pSrc1;
*
* DESCRIPTION
* Returns the absolute value of pSrc1 in pDst.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns pDst if successful, and returns GM_NULL on error.
*
* AUTHOR
* Andy Anderson 27-JAN-1987 19:00
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *AbsoluteDecimal(pDst,pSrc)
DEC *pDst,*pSrc;
{
_MacStart( GM_DABS );
_MacInVar(pSrc,GM_NULL);
_MacOutVar(pDst,GM_NULL);
/* Then check for negative number */
_MacDCopy(pDst,pSrc);
if (_MacIsDecN(pSrc)) {
_MacDChgs(pDst);
}
_MacRet(pDst);
}

80
gfm/dacos.c Executable file
View File

@ -0,0 +1,80 @@
/* DEC *ArcCosineDecimal(pDst,pSrc)
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc;
*
* DESCRIPTION
* Sets pDst = the arccosine (in radians) of pSrc,
* which always lies between 0 and pi
*
* RETURNS
* Returns pointer to pDst if successful, otherwise a GM_NULL.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_IMAG if | pSrc | > 1
*
* AUTHOR
* Jared Levy Aug 7, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *ArcCosineDecimal(pDst,pSrc)
DEC *pDst;
DEC *pSrc;
{
int isn = 0;
DEC *nsrc, dnsrc, *temp1, dtemp1, *temp2, dtemp2;
DEC *temp3, dtemp3, *temp4, dtemp4;
_MacStart(GM_DACOS);
_MacInVar(pSrc,GM_NULL);
_MacOutVar(pDst,GM_NULL);
nsrc = &dnsrc;
_MacDCopy(nsrc, pSrc);
if (_MacIsDecN(nsrc)) {
isn = 1;
_MacDChgs(nsrc);
}
if ((CompareDecimal(nsrc,&decOne)) == 1) {
_MacErr(GM_IMAG);
_MacRet(GM_NULL);
}
if (_MacIsDecZ(pSrc)) {
_MacDCopy(pDst,&decPiOver2);
_MacRet(pDst);
}
(void) _MulDec80Bit(temp1= &dtemp1, nsrc, nsrc);
(void) _SubDec80Bit(temp2= &dtemp2, &decOne, temp1);
_SqrtDec80Bit(temp3=&dtemp3, temp2);
if (_MacIsDecZ(temp3)) /* arcsin(1) = pi/2 */
{_MacDZero(pDst);}
else {
(void) _DivDec80Bit(temp4=&dtemp4, temp3, nsrc);
_ATanDec80Bit(pDst, temp4);
}
if (isn)
(void) _SubDec80Bit(pDst, &decPi, pDst);
/* reduce from 80-bit back to 64-bit */
(void) _Sq5UnsTo4Uns(pDst);
_MacRet(pDst);
}

127
gfm/dadd.c Executable file
View File

@ -0,0 +1,127 @@
/* DEC *AddDecimal(pDst,pSrc1,pSrc2)
*
* ARGUMENT
* pDst is a pointer to the destination DEC structure.
* pSrc1 is a ptr to the source1 DEC structure.
* pSrc2 is a ptr to the source2 DEC structure.
*
* DESCRIPTION
* Adds the value in pSrc1 DEC to the value in pSrc2 DEC
* and puts the result in dest DEC structure. The sum is calculated
* to the maximum possible accuracy. The routine requires MINID,
* the minimum allowed implied decimal.
*
* SIDE EFFECTS
* On overflow, the dest value is indeterminate.
*
* RETURNS
* Returns a pointer to the dest structure unless overflow,
* when it returns a GM_NULL.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
*
* AUTHOR
* Andy Anderson 13-JAN-1987 14:14
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gmsystem.h"
DEC *AddDecimal(pDst,pSrc1,pSrc2)
DEC *pDst;
DEC *pSrc1,*pSrc2;
{
DEC t1, t2, *pts;
register int i,j;
int s1, s2;
_MacStart(GM_DADD);
_MacInVar(pSrc1,GM_NULL);
_MacInVar(pSrc2,GM_NULL);
_MacOutVar(pDst,GM_NULL);
/* if the source id's are different, make them equal with as much accuracy
as is possible, and protect source fields from change */
/* line up decimal places */
i = pSrc1->dc.id-pSrc2->dc.id;
if (i) {
pts = &t1;
_MacDCopy(pts, pSrc1);
pts = &t2;
_MacDCopy(pts, pSrc2);
if (i<0) {
pSrc1 = &t1;
pSrc2 = &t2;
i = -i;
}
else {
pSrc2 = &t1;
pSrc1 = &t2;
}
j = _MulUnsArrByPwrOf10Limited(
pSrc1->dc.sl, i, 4);
pSrc1->dc.id += j;
if (j<i)
_DivUnsArrByPwrOf10(pSrc2->dc.sl, 4, i-j);
}
/* add the numbers */
pDst->dc.id = pSrc1->dc.id;
s1 = pSrc1->dc.attr & 0x0001;
s2 = pSrc2->dc.attr & 0x0001;
if (s1 == s2) {
/* add absolute values if signs are equal */
_AddUnsArrToUnsArr(pSrc1->dc.sl, pSrc2->dc.sl,
pDst->dc.sl,5);
/* if the first addition is an overflow, round down and try again */
if (pDst->dc.sl[3] >= 32768L) {
if (pSrc1->dc.id <= GM_MINID) {
_MacErr(GM_OVERFLOW);
_MacRet(GM_NULL);
}
_DivUnsArrByUns(pDst->dc.sl, 10, 4);
pDst->dc.id--;
}
/* sign of pDst same as sign of sources */
pDst->dc.attr = s1;
}
else {
/* subtract larger absolute value from smaller if signs are different */
if (_CompareUnsArr(pSrc1->dc.sl,
pSrc2->dc.sl, 4) >= 0) {
/* pSrc1 has larger absolute value */
(void) _SubUnsArrFromUnsArr(pSrc1->dc.sl,
pSrc2->dc.sl,
pDst->dc.sl,5);
/* sum has same sign as pSrc1 */
pDst->dc.attr = s1;
}
else {
/* pSrc2 has larger absolute value */
(void) _SubUnsArrFromUnsArr(pSrc2->dc.sl,
pSrc1->dc.sl,
pDst->dc.sl,5);
/* sum has same sign as pSrc2 */
pDst->dc.attr = s2;
}
}
_MacRet(pDst);
}

110
gfm/dadx.c Executable file
View File

@ -0,0 +1,110 @@
/* int _AddDec80Bit(pDst,pSrc1,pSrc2)
*
* ARGUMENT
* pDst is a pointer to the destination DEC structure.
* pSrc1 is a ptr to the source1 DEC structure.
* pSrc2 is a ptr to the source2 DEC structure.
*
* DESCRIPTION
* Adds the value in pSrc1 DEC to the value in pSrc2 DEC
* and puts the result in dest DEC structure. The sum is calculated
* to the maximum possible accuracy. The routine requires GM_IMINID,
* the minimum allowed implied decimal.
*
* SIDE EFFECTS
* On overflow, the *pDst value is indeterminate.
*
* RETURNS
* Returns GM_SUCCESS if no error, else failure code.
*
* Note: uses an assembly language routine for the actual math
*
* AUTHOR
* Jared Levy
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int _AddDec80Bit(pDst,pSrc1,pSrc2)
DEC *pDst;
DEC *pSrc1,*pSrc2;
{
DEC t1, t2, *pts;
register int i, j;
int s1, s2;
i = pSrc1->dc.id-pSrc2->dc.id;
if (i) {
pts = &t1;
_MacDCopy(pts, pSrc1);
pts = &t2;
_MacDCopy(pts, pSrc2);
if (i<0) {
pSrc1 = &t1;
pSrc2 = &t2;
i = -i;
}
else {
pSrc2 = &t1;
pSrc1 = &t2;
}
j = _MulUnsArrByPwrOf10Limited(pSrc1->dc.sl, i, 5);
pSrc1->dc.id += j;
if (j<i)
_DivUnsArrByPwrOf10(pSrc2->dc.sl, 5, i-j);
}
/* add the numbers */
pDst->dc.id = pSrc1->dc.id;
s1 = pSrc1->dc.attr & 0x0001;
s2 = pSrc2->dc.attr & 0x0001;
if (s1 == s2) {
/* add absolute values if signs are equal */
_AddUnsArrToUnsArr(pSrc1->dc.sl, pSrc2->dc.sl,
pDst->dc.sl,5);
/* if the first addition is an overflow, round down and try again */
if (pDst->dc.sl[4] >= 32768L) {
if (pSrc1->dc.id <= GM_IMINID)
return(GM_OVERFLOW);
_DivUnsArrByUns(pDst->dc.sl, 10, 5);
pDst->dc.id--;
}
/* sign of pDst same as sign of sources */
pDst->dc.attr = s1;
}
else {
/* subtract larger absolute value from smaller if signs are different */
if (_CompareUnsArr(pSrc1->dc.sl,
pSrc2->dc.sl, 5) >= 0) {
/* pSrc1 has larger absolute value */
(void) _SubUnsArrFromUnsArr(pSrc1->dc.sl,
pSrc2->dc.sl,
pDst->dc.sl,5);
/* sum has same sign as pSrc1 */
pDst->dc.attr = s1;
}
else {
/* pSrc2 has larger absolute value */
(void) _SubUnsArrFromUnsArr(pSrc2->dc.sl,
pSrc1->dc.sl,
pDst->dc.sl,5);
/* sum has same sign as pSrc2 */
pDst->dc.attr = s2;
}
}
return(GM_SUCCESS);
}

54
gfm/dalloc.c Executable file
View File

@ -0,0 +1,54 @@
/* DEC *AllocateDecimal();
*
* ARGUMENT
* None.
*
* DESCRIPTION
* Creates a DEC structure and zeroes it. The id is set to 2.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns pointer to the new structure if allocation is successful,
* otherwise returns GM_NULL. wGMError contains GM_NOMEMORY if no previous
* error existed.
*
* POSSIBLE ERROR CODES
*
* GM_NOMEMORY
*
* AUTHOR
* Andy Anderson 14-JAN-1987 16:15
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include <malloc.h>
#include "gm.h"
#include "gmsystem.h"
#ifndef DOS
extern char *calloc(unsigned ,unsigned );
#endif
DEC *AllocateDecimal()
{
DEC *a;
_MacStart(GM_DALLOC);
a=(DEC *) calloc(1,sizeof(DEC));
/* then make sure we pass back a good value */
if(!a) {
_MacErr(GM_NOMEMORY);
_MacRet(GM_NULL);
}
_MacDZero(a);
_MacRet(a);
}

98
gfm/dalog.c Executable file
View File

@ -0,0 +1,98 @@
/* DEC *AntiLog10Decimal(pDst,pSrc)
*
* ARGUMENT
* pDst is a DEC pointer to the destination.
* pSrc is a DEC pointer to the source.
*
* DESCRIPTION
* Takes the base 10 anti-logarithm (power) of pSrc,
* ie. 10**x, storing result in pDst.
*
* RETURNS
* pDst if successful, GM_NULL otherwise.
*
* ALGORITHM
* Set e**x = 10 ** y, then x*ln(e) = y*ln10. Then, ln(e)=1 by
* definition, so x = y*ln(10), or y times a constant. Therefore, we
* set z=y*ln(10), and 10**y = e**z.
*
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
* GM_UNDERFLOW
*
* AUTHOR
* Andy Anderson 8-18-87 13:51
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *AntiLog10Decimal(pDst,pSrc)
DEC *pDst;
DEC *pSrc;
{
int i;
DEC dtemp, *temp=&dtemp, *pt, t1;
_MacStart(GM_DALOG);
_MacInVar(pSrc,GM_NULL);
_MacOutVar(pDst,GM_NULL);
/* 10**0 is a one by definition */
if(_MacIsDecZ(pSrc)) {
pt=&decOne;
_MacDCopy(pDst,pt);
_MacRet(pDst);
}
pt=&t1;
_MacDZero(pt);
/* if the power is integer and small enough, use int power rtn */
if((IsDecimalInt(pSrc)) && ((pSrc->dc.msd == 0) &&
(pSrc->ls.lsl[1] == 0L) && (pSrc->dc.sl[1] == 0))
&& (!(pSrc->dc.sl[0] & 0x8000))) {
pt->dc.id = 0;
pt->dc.sl[0] = 10;
i = _IntPwrDec80Bit(pt,pt,ConvDecimalToInt(pSrc));
if(i != GM_SUCCESS) {
_MacErr(i);
_MacRet(GM_NULL);
}
}
else {
/* first create z = y*ln10, overflow impossible */
(void) _MulDec80Bit(temp,pSrc,&decLn10);
/* then e**(yln10) = 10**y */
i = _ExpDec80Bit(pt, temp);
if(i==GM_OVERFLOW) {
_MacErr(i);
_MacRet(GM_NULL);
}
}
i = _Sq5UnsTo4Uns(pt); /* reduce to 18-digit */
if(i!=GM_SUCCESS) {
_MacErr(GM_OVERFLOW);
_MacRet(GM_NULL);
}
if (_MacIsDecZ(pt)) {
_MacErr(GM_UNDERFLOW);
}
_MacDCopy(pDst,pt);
_MacRet(pDst);
}

81
gfm/daralloc.c Executable file
View File

@ -0,0 +1,81 @@
/* DEC **AllocateDecimalArray(dst, n);
*
* ARGUMENT
* int n;
* DEC **dst;
*
* DESCRIPTION
* Creates an array of n DEC pointers, each pointing to a DEC structure.
* All of the DEC structures are zeroed with in id of 2. If dst is null,
* both the pointers and the structures are allocated. Otherwise, when dst
* is not null, only the structures are allocated and each pointer points to
* the corresponding DEC structure.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns pointer to the new structure if allocation is successful,
* otherwise returns GM_NULLARR.
*
* POSSIBLE ERROR CODES
*
* GM_NOMEMORY
* GM_ARGVAL (if n == 0)
* GM_NULLPOINTER
*
* AUTHOR
* Jared Levy
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include <malloc.h>
#include "gm.h"
#include "gmsystem.h"
#ifndef DOS
extern char *calloc(unsigned ,unsigned );
#endif
DEC **AllocateDecimalArray(dst, n)
int n;
DEC **dst;
{
DEC *b, *p;
int i;
_MacStart(GM_DARALLOC);
if (n<=0) {
_MacErr(GM_ARGVAL);
_MacRet(GM_NULLARR);
}
if (!dst) {
_MacErr(GM_NULLPOINTER);
_MacRet(GM_NULLARR);
}
b = (DEC *) calloc(n,sizeof(DEC));
/* insufficient room for pointers */
if(!b) {
_MacErr(GM_NOMEMORY);
_MacRet(GM_NULLARR);
}
for (i=0; i<n; i++) {
p = &(b[i]);
dst[i] = p;
_MacDZero(p);
}
_MacRet(dst);
}

77
gfm/darcpy.c Executable file
View File

@ -0,0 +1,77 @@
/* DEC **CopyDecimalArray(pDst,pSrc,n)
*
* ARGUMENT
* pDst is a ptr to the array of destination DEC pointers.
* pSrc is a ptr to the array of source DEC pointers
* n is the number of elements in pSrc
*
* DESCRIPTION
* Copies pSrc to pDst. If pDst is null, tries to create a
* DEC array, then do the copy. If some of the pSrc structures
* are null, the non-null ones are still copied.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns pointer to the new structure if successful, otherwise
* returns GM_NULLARR.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_ARGVAL
*
* AUTHOR
* Andy Anderson 15-JAN-1987 18:45
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC **CopyDecimalArray(pDst,pSrc,n)
DEC **pDst;
DEC **pSrc;
int n;
{
int i;
mbool copyback; /* whether list is copied backwards */
/* source must be supplied !! */
_MacStart(GM_DARCPY);
if (!pSrc||!pDst) {
_MacErr(GM_NULLPOINTER);
_MacRet(GM_NULLARR);
}
if (n<0) {
_MacErr(GM_ARGVAL);
_MacRet(GM_NULLARR);
}
/* if n is 0 there's nothing to do */
if (n==0)
_MacRet(pDst);
/* allow for overlapping arrays */
copyback = (pDst > pSrc);
/* At any rate, copy the structure */
i = copyback ? n-1 : 0;
while ((i<n) && (i>=0)) {
(void) CopyDecimal(pDst[i], pSrc[i]);
/* CopyDecimal sets error flag if error occurs */
if (copyback)
i--;
else
i++;
}
_MacRet(pDst);
}

61
gfm/darfree.c Executable file
View File

@ -0,0 +1,61 @@
/* void FreeDecimalArray(pSrc1)
*
* ARGUMENT
* pSrc1 is a ptr to an array of source DEC pointers.
*
* DESCRIPTION
* Returns storage to DOS via free().
*
* SIDE EFFECTS
* Does NOT CHECK to see if spaces was allocated via malloc().
* Therefore, DOS will lock up cause cold reboot if unallocated
* space is freed
*
* RETURNS
* None.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Andy Anderson 17-JAN-1987 14:35
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include <malloc.h>
#include "gm.h"
#include "gmsystem.h"
void FreeDecimalArray(pSrc1)
DEC **pSrc1;
{
#ifdef LATTICE
void free();
#else
void free(void*);
#endif
DEC *p;
_MacStart(GM_DARFREE);
/* Can't free null pointers */
if(!pSrc1) {
_MacErr(GM_NULLPOINTER);
_MacRetV;
}
p = *pSrc1;
#ifdef LATTICE
free((char *) p);
#else
free((char *) p);
#endif
_MacRetV;
}

74
gfm/dasin.c Executable file
View File

@ -0,0 +1,74 @@
/* DEC *ArcSineDecimal(pDst,pSrc)
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc;
*
* DESCRIPTION
* Sets pDst = the arcsine (in radians) of pSrc,
* which always lies between -pi/2 and pi/2.
*
* RETURNS
* Returns pointer to pDst if successful, otherwise a GM_NULL.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_IMAG if | pSrc | > 1
*
* AUTHOR
* Jared Levy Aug 7, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *ArcSineDecimal(pDst,pSrc)
DEC *pDst;
DEC *pSrc;
{
int isn = 0;
DEC *nsrc, dnsrc, *temp1, dtemp1, *temp2, dtemp2;
DEC *temp3, dtemp3, *temp4, dtemp4;
_MacStart(GM_DASIN);
_MacInVar(pSrc,GM_NULL);
_MacOutVar(pDst,GM_NULL);
nsrc = &dnsrc;
_MacDCopy(nsrc, pSrc);
if (_MacIsDecN(nsrc)) {
isn = 1;
_MacDChgs(nsrc);
}
if ((CompareDecimal(nsrc,&decOne)) == 1) {
_MacErr(GM_IMAG);
_MacRet(GM_NULL);
}
(void) _MulDec80Bit(temp1= &dtemp1, nsrc, nsrc);
(void) _SubDec80Bit(temp2= &dtemp2, &decOne, temp1);
_SqrtDec80Bit(temp3=&dtemp3, temp2);
if (_MacIsDecZ(temp3)) /* arcsin(1) = pi/2 */
_MacDCopy(pDst, &decPiOver2);
else {
(void) _DivRndDec80Bit(temp4=&dtemp4, nsrc, temp3, 23);
_ATanDec80Bit(pDst, temp4);
}
/* reduce from 80-bit back to 64-bit */
(void) _Sq5UnsTo4Uns(pDst);
if (isn)
_MacDChgs(pDst);
_MacRet(pDst);
}

47
gfm/datan.c Executable file
View File

@ -0,0 +1,47 @@
/* DEC *ArcTangentDecimal(pDst,pSrc)
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc;
*
* DESCRIPTION
* Sets pDst = the arctangent (in radians) of pSrc,
* which always lies between -pi/2 and pi/2.
*
* RETURNS
* Returns pointer to pDst if successful, otherwise a GM_NULL.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_NOMEMORY
*
* AUTHOR
* Jared Levy Aug 7, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *ArcTangentDecimal(pDst,pSrc)
DEC *pDst;
DEC *pSrc;
{
_MacStart(GM_DATAN);
_MacInVar(pSrc,GM_NULL);
_MacOutVar(pDst,GM_NULL);
_ATanDec80Bit(pDst, pSrc);
/* reduce from 80-bit back to 64-bit */
(void) _Sq5UnsTo4Uns(pDst);
_MacRet(pDst);
}

83
gfm/datax.c Executable file
View File

@ -0,0 +1,83 @@
/* void _ATanDec80Bit(pDst,pSrc)
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc;
*
* DESCRIPTION
* Sets pDst = the arctangent (in radians) of pSrc,
* which always lies between -pi/2 and pi/2.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* None. (always successful)
*
* AUTHOR
* Jared Levy Aug 7, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* ALGORITHM
* For x < 0, atan(x) = - atan(-x)
* For x > 1 atan(x) = pi / 2 - acot(x) = pi / 2 - atan(1 / x)
* atan(x) = pi / 6 + atan [ (x - 1/3^.5) / (1 + x/3^.5) ]
* atan(x) = x - x^3/3 + x^5/5 - ...
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
void _ATanDec80Bit(pDst,pSrc)
DEC *pDst;
DEC *pSrc;
{
int isn=0, isrecip=0;
DEC *nsrc, dnsrc, *x, dx, *xsq, dxsq, *xpow, dxpow;
DEC *term, dterm, *fact, dfact;
DEC *num, dnum, *den, dden, *temp, dtemp;
nsrc = &dnsrc;
_MacDCopy(nsrc, pSrc);
if (_MacIsDecN(nsrc)) {
isn = 1;
_MacDChgs(nsrc);
}
if (CompareDecimal(nsrc,&decOne) == 1) {
isrecip = 1;
(void) _DivRndDec80Bit(nsrc, &decOne, nsrc, 23);
}
(void) _SubDec80Bit(num = &dnum, nsrc, &decReciprocalOfSqrt3);
(void) _MulDec80Bit(temp = &dtemp, &decReciprocalOfSqrt3, nsrc);
(void) _AddDec80Bit(den = &dden, temp, &decOne);
(void) _DivRndDec80Bit(x = &dx, num, den, 23);
(void) _MulDec80Bit(xsq = &dxsq, x , x);
(void) _MulDec80Bit(xpow = &dxpow, xsq, x);
_MacDCopy(pDst, x);
(void) ConvLongToDecimal(fact = &dfact, 3L);
(void) _DivRndDec80Bit(term = &dterm, xpow, fact, 23);
while (!_MacIsDecZ(term)) {
if ((fact->dc.sl[0] % 4) == 1)
(void) _AddDec80Bit(pDst, pDst, term);
else
(void) _SubDec80Bit(pDst, pDst, term);
fact->dc.sl[0]+= 2;
(void) _MulDec80Bit(xpow, xpow, xsq);
(void) _DivRndDec80Bit(term, xpow, fact, 23);
}
(void) _AddDec80Bit(pDst, &decPiOver6, pDst);
if (isrecip)
(void) _SubDec80Bit(pDst, &decPiOver2, pDst);
if (isn)
_MacDChgs(pDst);
}

59
gfm/dbd360.c Executable file
View File

@ -0,0 +1,59 @@
/* int DaysBetweenDates360(m1,d1,y1, m2,d2,y2)
*
* ARGUMENT
* int m1,d1,y1; - Base Date
* int m2,d2,y2; - Date to compare with base
*
* DESCRIPTION
* Compares two dates in date args format, forming the difference in
* whole days. The result is a signed number:
*
* In this one, all months are 30 days (e.g. year is 360 days).
*
* 0 if dates are same,
* +n if date1 > date2
* -n if date1 < date2
*
* SIDE EFFECTS
* None.
*
* RETURNS
* +,-, or 0 days. 0 can indicate an error.
*
* POSSIBLE ERROR CODES
* GM_ARGVAL
* GM_OVERFLOW
*
* AUTHOR
* 05-Aug-1987 12:43:39
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*/
#include <stdio.h>
#include "gmsystem.h"
int DaysBetweenDates360(m1,d1,y1,m2,d2,y2)
int m1,d1,y1,m2,d2,y2;
{
long n;
_MacStart(GM_DBD360);
if (m1<1||m1>12||d1<1||d1>31||y1<0||y1>9999||
m2<1||m2>12||d2<1||d2>31||y2<0||y2>9999) {
_MacErr(GM_ARGVAL);
_MacRet(0);
}
if (d2==31)
d2=30;
if (d1==31 && d2>=30)
d1=30;
n = (long) (y1-y2) * 360L + (long) ((m1 - m2) * 30 + (d1 - d2));
if (n<-32768L || n>32767L) {
_MacErr(GM_OVERFLOW);
_MacRet(0);
}
_MacRet((int) n);
}

143
gfm/dbd365.c Executable file
View File

@ -0,0 +1,143 @@
/* int DaysBetweenDates365(m1,d1,y1, m2,d2,y2)
*
* ARGUMENT
* int m1,d1,y1; - Base Date
* int m2,d2,y2; - Date to compare with base
*
* DESCRIPTION
* Compares two dates in date args format, forming the difference in
* whole days. The result is a signed number:
*
* 0 if dates are same,
* +n if date1 > date2
* -n if date1 < date2
*
* SIDE EFFECTS
* None.
*
* RETURNS
* +,-, or 0 days. 0 can indicate an error.
*
* POSSIBLE ERROR CODES
* GM_ARGVAL
* GM_OVERFLOW
*
* AUTHOR
* 05-Aug-1987 12:43:39
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
* 01-Jan-1989 Corrected for true Gregorian Calendar
*
* DISCUSSION
*
* It may not be entirely clear when reading this code just what is going
* on. First of all, the calendar used is the Greenleaf version of the
* Gregorian calendar. We assume in this calendar that Gregorian time
* extends backwards to the year 0, and forward forever, more or less.
* A leap year occurs every four years. Except when the year is evenly
* divisible by 100, like the year 1900, when there is no leap year. Except
* when the year is evenly divisible by 400, in which case there really
* is a leap year.
*
* The way this algorithm works is relatively simple. There are four
* mysterious variables in this program: n1, n2, x and z. n1 and n2 are
* relatively easy to understand. These variables are simple the number
* of days since January 1, year 0. The difference between these two numbers
* is the actual number returned by this function.
*
* In order to calculate the number of days since 1/1/0, we can start by
* adding 365 days per year:
*
* n = 365 * y
*
* This gets a pretty good rough number, but it doesn't take into account
* the leap years. Given the Greenleaf Gregorian calendar, we can add in
* all the days accounted for by leap years like this:
*
* n = 365 * y + y/4 - y/100 + y/400
*
* This works pretty well, but it leaves us with one problem: we are
* adding in a leap day in leap years, even if the month is January
* or February. On January 1, 1984, we haven't hit the leap day yet, so
* we shouldn't add it in. This is where z comes from. y is the actual
* year, but z is the year used for calculation of leap days:
*
* if ( m <= 2 )
* z = y - 1;
* else
* z = y;
* n = 365 * y + y/4 - y/100 + y/400
*
* At this point, n is accurate for January 1 of the given year. Now we
* have to add in the days accounted for by the months in the selected year.
* A good guess on how to do this is to just add 31 days per month:
*
* n = 365 * y + y/4 - y/100 + y/400 + 31*(m - 1)
*
* The only problem is that starting with month 3, there will be errors
* in the calculation. The good news is that a simple formula will generate
* a correction factor, which is x. The formula for x is (4*m + 23) / 10.
* This just happens to generate the correct sequence of numbers. A different
* way would be to create an x array {0, 0, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7};
* So now my formula looks like this:
*
* if ( m <= 2 ) {
* x = 0;
* z = y - 1;
* } else {
* z = y;
* x = ( 4 * m + 23 ) / 10 ;
* }
* n = 365 * y + y/4 - y/100 + y/400 + 31*(m - 1)
*
* The final step is to add in the day of the month, to account for all the
* days in the current month. Do that and you are done.
*
*/
#include <stdio.h>
#include "gmsystem.h"
int DaysBetweenDates365(m1,d1,y1,m2,d2,y2)
int m1,d1,y1,m2,d2,y2;
{
long n1, n2, n;
int x, z;
_MacStart(GM_DBD365);
if (m1<1||m1>12||d1<1||d1>31||y1<0||y1>9999||
m2<1||m2>12||d2<1||d2>31||y2<0||y2>9999) {
_MacErr(GM_ARGVAL);
_MacRet(GM_ARGVAL);
}
if (m1<=2) {
x=0;
z=y1-1;
} else {
x=(4*m1 + 23) / 10;
z=y1;
}
n1 = (long) y1 * 365L + (long) (31*(m1-1) + d1 + z/4 - z/100 + z/400 - x);
if (m2<=2) {
x=0;
z=y2-1;
} else {
x=(4*m2 + 23) / 10;
z=y2;
}
n2 = (long) y2 * 365L + (long) (31*(m2-1) + d2 + z/4 - z/100 + z/400 - x);
n = n1 - n2;
if (n<-32768L||n>32767L) {
_MacErr(GM_OVERFLOW);
_MacRet(GM_OVERFLOW);
}
_MacRet((int) n);
}

74
gfm/dbdnly.c Executable file
View File

@ -0,0 +1,74 @@
/* int DaysBetweenDates365NoLeapYear(m1,d1,y1, m2,d2,y2)
*
* ARGUMENT
* int m1,d1,y1; - Base Date
* int m2,d2,y2; - Date to compare with base
*
* DESCRIPTION
* Compares two dates in date args format, forming the difference in
* whole days. The result is a signed number:
*
* 0 if dates are same,
* +n if date1 > date2
* -n if date1 < date2
*
* A 365 day calendar without leap years is used.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* +,-, or 0 days. 0 can indicate an error.
*
* POSSIBLE ERROR CODES
* GM_ARGVAL
* GM_OVERFLOW
*
* AUTHOR
* 05-Aug-1987 12:43:39
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*/
#include <stdio.h>
#include "gmsystem.h"
int DaysBetweenDates365NoLeapYear(m1,d1,y1,m2,d2,y2)
int m1,d1,y1,m2,d2,y2;
{
long n1, n2, n;
int x;
_MacStart(GM_DBDNLY);
if (m1<1||m1>12||d1<1||d1>31||y1<0||y1>9999||
m2<1||m2>12||d2<1||d2>31||y2<0||y2>9999) {
_MacErr(GM_ARGVAL);
_MacRet(GM_ARGVAL);
}
if (m1<=2) {
x=0;
}
else {
x=(4*m1 + 23) / 10;
}
n1 = (long) y1 * 365L + (long) (31*(m1-1) + d1 - x);
if (m2<=2) {
x=0;
}
else {
x=(4*m2 + 23) / 10;
}
n2 = (long) y2 * 365L + (long) (31*(m2-1) + d2 - x);
n = n1 - n2;
if (n<-32768L||n>32767L) {
_MacErr(GM_OVERFLOW);
_MacRet(GM_OVERFLOW);
}
_MacRet((int) n);
}

47
gfm/dchgs.c Executable file
View File

@ -0,0 +1,47 @@
/* DEC *ChangeSignDecimal(pDst,pSrc1)
*
* ARGUMENT
* DEC* pDst ptr to the destination DEC structure.
* DEC* pSrc1 ptr to the source1 DEC structure.
*
* DESCRIPTION
* Sets pDst=-(pSrc1).
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns a pointer to the DEC structure unless overflow.
* GM_NULL if an overflow occurs.
*
* POSSIBLE ERROR CODES:
*
* GM_NULLPOINTER
* GM_NOMEMORY
*
* AUTHOR
* Andy Anderson 13-JAN-1987 17:20
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *ChangeSignDecimal(pDst,pSrc)
DEC *pDst,*pSrc;
{
_MacStart(GM_DCHGS);
_MacInVar(pSrc,GM_NULL);
_MacOutVar(pDst,GM_NULL);
_MacDCopy(pDst,pSrc);
_MacDChgs(pDst);
_MacRet(pDst);
}

61
gfm/dchix.c Executable file
View File

@ -0,0 +1,61 @@
/* int _ScaleDec80Bit(pDst,pSrc1,wID)
*
* ARGUMENT
* pDst is a pointer to the destination DEC structure.
* pSrc1 is a ptr to the source1 DEC structure.
* wID is the integer specifying location of implied decimal
* for the conversion.
*
* DESCRIPTION
* Adjusts the number in pSrc1 (if necessary) while copying it to
* pDst adjusting pDst to wID number of decimal places. If pDst is null
* on entry, tries to first create a pDst, then the conversion.
*
* SIDE EFFECTS
* pSrc1 remains unchanged, pDst is undefined on error.
*
* RETURNS
* Returns GM_SUCCESS unless there is an error,
* in which case it returns the error code.
*
*
* AUTHOR
* Andy Anderson 27-JAN-1987 19:25
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int _ScaleDec80Bit(pDst,pSrc1,wID)
DEC *pDst, *pSrc1;
int wID;
{
register int i;
_MacDCopy(pDst,pSrc1);
i = pSrc1->ls.lid - wID;
/* Make sure there's an adjustment to do */
if(i == 0) {
return(GM_SUCCESS);
}
/* set implied decimal */
pDst->ls.lid = wID;
if(i>0) {
_DivUnsArrByPwrOf10( pDst->dc.sl,5,i);
}
else {
if((_MulUnsArrByPwrOf10( pDst->dc.sl, -i, 5)
!= GM_SUCCESS) || (pDst->dc.msd & 0x8000))
return(GM_OVERFLOW);
}
return(GM_SUCCESS);
}

76
gfm/dcmp.c Executable file
View File

@ -0,0 +1,76 @@
/* int CompareDecimal(pSrc1,pSrc2)
*
* ARGUMENT
* pSrc1 is a ptr to the source1 DEC structure.
* pSrc2 is a ptr to the source2 DEC structure.
*
* DESCRIPTION
* Compares pSrc1:pSrc2 and returns the result of the compare.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns 0 if pSrc1==pSrc2, 1 if pSrc1>pSrc2 and -1 if pSrc2>pSrc1.
* However, returns GM_NULLPOINTER if pSrc1 or pSrc2 point to a null.
*
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Andy Anderson 14-JAN-1987 14:27
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int CompareDecimal(pSrc1,pSrc2)
DEC *pSrc1,*pSrc2;
{
int i;
DEC dt,*pt=&dt;
_MacStart(GM_DCMP);
_MacInVarI(pSrc1);
_MacInVarI(pSrc2);
if (_MacIsDecZ(pSrc2))
_MacRet(TestSignDecimal(pSrc1));
if (_MacIsDecZ(pSrc1))
_MacRet(-TestSignDecimal(pSrc2));
if (_MacIsDecN(pSrc1)^_MacIsDecN(pSrc2))
_MacRet(_MacIsDecP(pSrc1) ? 1 : -1);
if (pSrc1->dc.id == pSrc2->dc.id) {
i=_CompareUnsArr( pSrc1->dc.sl,
pSrc2->dc.sl,5);
_MacRet(_MacIsDecP(pSrc1) ? i : -i);
}
if (pSrc1->dc.id > pSrc2->dc.id) {
i= _ScaleDec80Bit(&dt, pSrc2, pSrc1->dc.id);
if (i != GM_SUCCESS)
_MacRet(-TestSignDecimal(pSrc2));
i=_CompareUnsArr( pSrc1->dc.sl,
pt->dc.sl,5);
_MacRet(_MacIsDecP(pSrc1) ? i : -i);
}
/* pSrc1->dc.id < pSrc2->dc.id */
i= _ScaleDec80Bit(&dt, pSrc1, pSrc2->dc.id);
if (i != GM_SUCCESS)
_MacRet(TestSignDecimal(pSrc1));
i=_CompareUnsArr( pt->dc.sl,
pSrc2->dc.sl,5);
_MacRet(_MacIsDecP(pSrc2) ? i : -i);
}

46
gfm/dcos.c Executable file
View File

@ -0,0 +1,46 @@
/* DEC *CosineDecimal(pDst,pSrc)
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc;
*
* DESCRIPTION
* Sets pDst = the cosine of pSrc radians.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns pointer to pDst if successful, otherwise a GM_NULL.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Jared Levy Oct 16, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *CosineDecimal(pDst,pSrc)
DEC *pDst;
DEC *pSrc;
{
_MacStart(GM_DCOS);
_MacInVarD(pDst);
_MacOutVarD(pSrc);
_CosDec80Bit(pDst, pSrc);
(void) _Sq5UnsTo4Uns(pDst);
_MacRet(pDst);
}

56
gfm/dcoss.c Executable file
View File

@ -0,0 +1,56 @@
/* void _CosDecSmall(pDst,pSrc)
*
* ARGUMENT
* DEC *pDst, *pSrc;
*
* DESCRIPTION
* Sets pDst = cos(pSrc), where 0 <= pSrc < pi / 4.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* None.
*
* ALGORITHM
* Using the Taylor series,
* cos(x) = 1 - x^2/2! + x^4/4! - ...
*
* AUTHOR
* Jared Levy April 7, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
void _CosDecSmall(pDst,pSrc)
DEC *pDst, *pSrc;
{
DEC *srcsq, dsrcsq, *term, dterm, *fact, dfact;
SHORT i;
srcsq = &dsrcsq;
(void) _MulDec80Bit(srcsq, pSrc, pSrc);
(void) ConvLongToDecimal(pDst, 1L);
term = &dterm;
(void) _MulDec80Bit(term, srcsq, &decPoint5);
i = 2;
fact = ConvLongToDecimal(&dfact, 6L);
while (!(_MacIsDecZ(term))) {
if ((i % 4) == 0)
(void) _AddDec80Bit(pDst, pDst, term);
else
(void) _SubDec80Bit(pDst, pDst, term);
i+=2;
_MulDec80Bit(term, term, srcsq);
fact->dc.sl[0] = i * (i - 1);
_DivRndDec80Bit(term, term, fact, 23);
}
}

97
gfm/dcot.c Executable file
View File

@ -0,0 +1,97 @@
/* DEC *CotangentDecimal(pDst,pSrc)
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc;
*
* DESCRIPTION
* Sets pDst = the cotangent of pSrc radians.
*
* RETURNS
* Returns pointer to pDst if successful, otherwise a GM_NULL.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
* GM_IMAG if pSrc = 0
*
* AUTHOR
* Jared Levy Oct 16, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* ALGORITHM
* tan(x) = +/- (1 - cos(x) ^ 2 ) ^ .5 / cos(x)
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *CotangentDecimal(pDst,pSrc)
DEC *pDst;
DEC *pSrc;
{
int i, isn=0;
DEC *nsrc, dnsrc, *size, dsize, *temp, dtemp;
DEC *cosx, dcosx, *sinx, dsinx;
_MacStart(GM_DCOT);
_MacInVarD(pSrc)
_MacOutVarD(pDst);
if(_MacIsDecZ(pSrc)) {
_MacErr(GM_IMAG);
_MacRet(GM_NULL);
}
nsrc = &dnsrc;
(void) _SubDec80Bit(nsrc, &decPiOver2, pSrc);
if (_MacIsDecN(nsrc)) {
isn = 1;
_MacDChgs(nsrc);
}
temp = &dtemp;
if (CompareDecimal(nsrc, &decPiOver2) == 1) {
(void) _DivRndDec80Bit(size = &dsize, nsrc, &decPi, 0);
(void) _MulDec80Bit(temp, &decPi, size);
(void) _SubDec80Bit(nsrc, nsrc, temp);
if (_MacIsDecN(nsrc)) {
isn = 1 - isn;
_MacDChgs(nsrc);
}
}
_CosDec80Bit(cosx = &dcosx, nsrc);
if (_MacIsDecZ(cosx)) {
_MacErr(GM_OVERFLOW);
_MacRet(GM_NULL);
}
(void) _MulDec80Bit(temp, cosx, cosx);
(void) _SubDec80Bit(temp, &decOne, temp);
_SqrtDec80Bit(sinx = &dsinx, temp);
i = _DivDec80Bit(pDst, sinx, cosx);
if (i == GM_OVERFLOW) {
_MacErr(GM_OVERFLOW);
_MacRet(GM_NULL);
}
i = _Sq5UnsTo4Uns(pDst);
if (i != GM_SUCCESS) {
_MacErr(GM_OVERFLOW);
_MacRet(GM_NULL);
}
if (isn)
_MacDChgs(pDst);
_MacRet(pDst);
}

67
gfm/dcox.c Executable file
View File

@ -0,0 +1,67 @@
/* void _CosDec80Bit(pDst,pSrc)
*
* ARGUMENT
* DEC *pDst, *pSrc;
*
* DESCRIPTION
* Sets pDst = the cosine of pSrc radians.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* None. No errors are possible.
*
* AUTHOR
* Jared Levy October 16, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
void _CosDec80Bit(pDst,pSrc)
DEC *pDst, *pSrc;
{
DEC dnsrc, *nsrc, dtemp, *temp;
int isn=0;
nsrc = &dnsrc;
_MacDCopy(nsrc, pSrc);
/* scale nsrc to range 0 to pi */
if (_MacIsDecN(nsrc))
_MacDChgs(nsrc);
if (CompareDecimal(nsrc, &decPi) == 1) {
temp = &dtemp;
(void) _DivRndDec80Bit(temp, nsrc, &dec2Pi, 0);
(void) _MulDec80Bit(temp, temp, &dec2Pi);
(void) _SubDec80Bit(nsrc, nsrc, temp);
if (_MacIsDecN(nsrc))
_MacDChgs(nsrc);
}
/* scale nsrc to range 0 to pi / 2 */
if (CompareDecimal(nsrc, &decPiOver2) == 1) {
isn = 1;
(void) _SubDec80Bit(nsrc, &decPi, nsrc);
}
/* calculate appropriate Taylor series */
if (CompareDecimal(nsrc, &decPiOver4) == 1) {
(void) _SubDec80Bit(nsrc, &decPiOver2, nsrc);
_SinDecSmall(pDst, nsrc); /* sine series */
}
else
_CosDecSmall(pDst, nsrc); /* cosine series */
/* adjust for negative values */
if (isn)
_MacDChgs(pDst);
}

49
gfm/dcpy.c Executable file
View File

@ -0,0 +1,49 @@
/* DEC *CopyDecimal(pDst,pSrc1)
*
* ARGUMENT
* pDst is a ptr to the source1 DEC structure.
* pSrc1 is a ptr to the source2 DEC structure.
*
* DESCRIPTION
* Copies pSrc1 to pDst. If pDst is null, tries to create a
* DEC structure, then do the copy.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns pointer to the new structure if successful, otherwise
* returns GM_NULL. If pSrc1 point to a null, returns GM_NULLPOINTER.
*
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Andy Anderson 15-JAN-1987 18:45
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *CopyDecimal(pDst,pSrc)
DEC *pDst;
DEC *pSrc;
{
/* source must be supplied !! */
_MacStart(GM_DCPY);
_MacInVar(pSrc,GM_NULL);
_MacOutVar(pDst,GM_NULL);
_MacDCopy(pDst,pSrc);
_MacRet(pDst);
}

63
gfm/dctod.c Executable file
View File

@ -0,0 +1,63 @@
/* DEC *ConvDollarsAndCentsToDecimal( x, d, c)
*
* ARGUMENT
* DEC *x; output
* long l; dollars
* int c; cents
*
* DESCRIPTION
* Converts d dollars and c cents to a DEC with implied decimal 2.
*
* SIDE EFFECTS
* x is indeterminate on error.
*
* RETURNS
* The DEC if the conversion is successful, and GM_NULL otherwise.
*
* POSSIBLE ERROR CODES
* GM_NULLPOINTER
*
* AUTHOR
* Jared Levy Oct. 10, 1989
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gmsystem.h"
DEC *ConvDollarsAndCentsToDecimal( x, d, c)
DEC *x;
long d;
int c;
{
int isneg=0;
_MacStart(GM_DCTOD);
_MacOutVarD(x);
if (d<0) {
isneg = 1;
d = -d;
c = (c<0) ? -c : c;
}
x->ls.lmsd = 0;
x->ls.lsl[1] = 0L;
if (d<=21470000L)
x->ls.lsl[0] = d * 100L + (long) c;
else {
x->ls.lsl[0] = d;
_MulUnsArrByPwrOf10(x->dc.sl, 2, 3);
x->ls.lsl[0] += (long) c;
if (x->ls.lsl[0] < (unsigned long) c && c>0)
x->ls.lsl[1]--;
}
x->ls.lid = 2;
x->ls.lattr = isneg;
_MacRet(x);
}

46
gfm/ddeg.c Executable file
View File

@ -0,0 +1,46 @@
/* DEC *ConvRadiansToDegrees(deg, rad);
*
* ARGUMENT
* DEC *deg;
* DEC *rad;
*
* DESCRIPTION
* Converts an angle rad, in radians, to degrees,
* storing the result in deg.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* rad if successful, otherwise GM_NULL
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_INIT
* GM_OVERFLOW
*
* AUTHOR
* Jared Levy
* Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gmsystem.h"
DEC *ConvRadiansToDegrees(deg, rad)
DEC *deg;
DEC *rad;
{
int i;
_MacStart(GM_DDEG);
i = _MulDec80Bit( deg, &dec180OverPi, rad );
if ( i != GM_SUCCESS ) {
_MacErr( i );
_MacRet( GM_NULL );
}
(void) _Sq5UnsTo4Uns( deg );
_MacRet( deg );
}

60
gfm/ddiv.c Executable file
View File

@ -0,0 +1,60 @@
/* DEC *DivideDecimal(pDst,pSrc1,pSrc2);
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc1,pSrc2;
*
* DESCRIPTION
* Divides pSrc1 by pSrc2, storing the result in pDst. The quotient is
* calculated to as much accuracy as posssible, subject to the constraint
* that its implied decimal must lie between MINID and MAXID.
*
* SIDE EFFECTS
* pDst is indeterminate on underflow or overflow.
* GM_OVERFLOW: quotient too large.
* GM_UNDERFLOW: pSrc1 != 0, pSrc2 != 0, pDst = 0.
*
* RETURNS
* Returns pointer to pDst if successful, otherwise a GM_NULL. The
* type error (GM_OVERFLOW, GM_UNDERFLOW, GM_NOMEMORY) is in wGMError
* if wGMError doesn't contain a previous error.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
* GM_UNDERFLOW
* GM_DIV0
*
* AUTHOR
* Jared Levy 05-JAN-1987 17:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gmsystem.h"
DEC *DivideDecimal(pDst,pSrc1,pSrc2)
DEC *pDst;
DEC *pSrc1,*pSrc2;
{
int i;
_MacStart(GM_DDIV);
_MacInVarD(pSrc1);
_MacInVarD(pSrc2);
_MacOutVarD(pDst);
i = _DivDecFast(pDst, pSrc1, pSrc2);
if (i != GM_SUCCESS) {
_MacErr(i);
_MacRet(GM_NULL);
}
_MacRet(pDst);
}

149
gfm/ddivpf.c Executable file
View File

@ -0,0 +1,149 @@
/* int _DivProcFast(c,a,b);
*
* ARGUMENT
* DEC *c;
* DEC *a,b;
*
* DESCRIPTION
* This routine divides one positive DEC structure by another, setting
* dst = src1 / src2.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* None.
*
* ALGORITHM
* a = an * 10^-ad
* b = bn * 10^-bd
* c = a / b
* c = (10^p * an / bn) * 10^[-(ad - bd + p)]
* cn = 10^p * an / bn, cd = ad - bd + p
*
* AUTHOR
* Jared Levy 05-JAN-1987 17:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int _DivProcFast(c,a,b)
DEC *c;
DEC *a,*b;
{
register int i,t;
int maxp, p=0, mag2a, mag2b;
unsigned SHORT an[14], bn[6], *cn, ad[5], as[14];
/* sets c = a / b,
where a and b are positive DEC numbers, and the result is stored in c */
bn[0]=b->dc.sl[0];
bn[1]=b->dc.sl[1];
bn[2]=b->dc.sl[2];
bn[3]=b->dc.sl[3];
bn[4]=b->dc.msd;
bn[5]=0;
cn = c->dc.sl;
an[0]=a->dc.sl[0];
an[1]=a->dc.sl[1];
an[2]=a->dc.sl[2];
an[3]=a->dc.sl[3];
an[4]=a->dc.msd;
an[5] = 0;
an[6] = 0;
an[7] = 0;
an[8] = 0;
an[9] = 0;
an[10]= 0;
an[11]= 0;
maxp = GM_MAXID - (a->dc.id - b->dc.id);
if (maxp > 0) {
/* The following code uses up most of the time involved in divisions.
It starts with two 64-bit number integers an and bh, both positive,
along with an integer maxp. Two values are returned: a nonnegative
integer p and a 160-bit number as = an * 10^p. p is the largest number
satisfying the conditions (1) as < 2^160,
(2) the highest 80 bits of as are less than bh
(3) p <= maxp.
*/
i = 4;
while (an[i] == 0)
i--;
mag2a = 16 * i;
t = an[i]>>1;
while (t) {
t=t>>1;
mag2a++;
}
i = 4;
while ((bn[i] == 0) && (i>0))
i--;
mag2b = 16 * i;
t = bn[i]>>1;
while (t) {
t=t>>1;
mag2b++;
}
p = (78 - 16 + mag2b - mag2a) * 3 / 10;
if (p>maxp)
p=maxp;
if (p != 0)
_MulUnsArrByPwrOf10(an,p,10);
if (p != maxp) {
for(i=0; i<14; i++) {
as[i] = an[i];
}
i = _MulUnsArrByPwrOf10(as,1,10);
ad[0]=as[4];
ad[1]=as[5];
ad[2]=as[6];
ad[3]=as[7];
ad[4]=as[8];
_DoubleUnsArr(ad, 5);
if (as[4]&0x8000)
ad[0]=ad[0]+1;
if ((i == GM_SUCCESS) &&
(_CompareUnsArr(ad,bn,5) == -1)) {
p++;
for(i=0; i<10; i++)
an[i] = as[i];
}
}
/* p != maxp */
} /* maxp > 0 */
_DivUns10ArrByUns5Arr(cn,an,bn);
/* adjust implied decimal to correct value */
i = a->dc.id - b->dc.id + p;
if (i<GM_MINID)
return(GM_OVERFLOW);
if (i>GM_MAXID) {
_DivUnsArrByPwrOf10(cn, 5, i-GM_MAXID);
i = GM_MAXID;
}
c->dc.id = i;
return(GM_SUCCESS);
}

86
gfm/ddivpr.c Executable file
View File

@ -0,0 +1,86 @@
/*int _DivProcRnd(c,a,b,ida,idb,nid)
*
* ARGUMENT
* DEC *c;
* unsigned a[], b[];
* int ida,idb,nid;
*
* DESCRIPTION
* This routine divides one positive DEC structure by another, setting
* dst = src1 / src2.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* GM_SUCCESS or error code.
*
* ALGORITHM
* a = an * 10^-ad
* b = bn * 10^-bd
* c = a / b
* c = (10^p * an / bn) * 10^[-(ad - bd + p)]
* cn = 10^p * an / bn, cd = ad - bd + p
*
* AUTHOR
* Jared Levy 05-JAN-1987 17:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int _DivProcRnd(c,a,b,ida,idb,nid)
DEC *c;
unsigned SHORT a[], b[];
int ida,idb,nid;
{
int i, p;
unsigned SHORT *cn, ad[5];
/* sets c = a / b,
where a and b are positive DEC numbers, and the result is stored in c */
cn = c->dc.sl;
p = nid - (ida - idb);
a[5] = 0;
a[6] = 0;
a[7] = 0;
a[8] = 0;
a[9] = 0;
a[10]= 0;
a[11]= 0;
if (p<0)
_DivUnsArrByPwrOf10(a,5,-p);
if (p>0) {
i = _MulUnsArrByPwrOf10(a,p,10);
/* check for overflow */
ad[0]=a[5];
ad[1]=a[6];
ad[2]=a[7];
ad[3]=a[8];
ad[4]=a[9];
_DoubleUnsArr(ad, 5);
if (a[4]&0x8000)
ad[0]=ad[0]+1;
if (!((i == GM_SUCCESS) &&
(_CompareUnsArr(ad,b,5) == -1)))
return(GM_OVERFLOW);
}
_DivUns10ArrByUns5Arr(cn, a, b);
c->dc.id = nid;
return(GM_SUCCESS);
}

86
gfm/ddivpt.c Executable file
View File

@ -0,0 +1,86 @@
/*int _DivProcTrn(c,a,b,ida,idb,nid)
*
* ARGUMENT
* DEC *c;
* unsigned a[], b[];
* int ida,idb,nid;
*
* DESCRIPTION
* This routine divides one positive DEC structure by another, setting
* dst = src1 / src2.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* GM_SUCCESS or error code.
*
* ALGORITHM
* a = an * 10^-ad
* b = bn * 10^-bd
* c = a / b
* c = (10^p * an / bn) * 10^[-(ad - bd + p)]
* cn = 10^p * an / bn, cd = ad - bd + p
*
* AUTHOR
* Jared Levy 05-JAN-1987 17:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int _DivProcTrn(c,a,b,ida,idb,nid)
DEC *c;
unsigned SHORT a[], b[];
int ida,idb,nid;
{
int i, p;
unsigned SHORT *cn, ad[5];
/* sets c = a / b,
where a and b are positive DEC numbers, and the result is stored in c */
cn = c->dc.sl;
p = nid - (ida - idb);
a[5] = 0;
a[6] = 0;
a[7] = 0;
a[8] = 0;
a[9] = 0;
a[10]= 0;
a[11]= 0;
if (p<0)
_DivUnsArrByPwrOf10Trunc(a,5,-p);
if (p>0) {
i = _MulUnsArrByPwrOf10(a,p,10);
/* check for overflow */
ad[0]=a[5];
ad[1]=a[6];
ad[2]=a[7];
ad[3]=a[8];
ad[4]=a[9];
_DoubleUnsArr(ad, 5);
if (a[4]&0x8000)
ad[0]=ad[0]+1;
if (!((i == GM_SUCCESS) &&
(_CompareUnsArr(ad,b,5) == -1)))
return(GM_OVERFLOW);
}
_DivUns10ArrByUns5ArrTrn(cn, a, b);
c->dc.id = nid;
return(GM_SUCCESS);
}

75
gfm/ddivr.c Executable file
View File

@ -0,0 +1,75 @@
/* DEC *DivideDecimalAndRound(dst,src1,src2,nid);
*
* ARGUMENT
* DEC *dst;
* DEC *src1,*src2;
* int nid;
*
* DESCRIPTION
* Divides src1 by src2, storing the result in dst. The quotient is
* calculated to nid decimal places.
*
* RETURNS
* Returns pointer to dst if successful, otherwise a GM_NULL. The
* type error (GM_OVERFLOW, GM_UNDERFLOW, GM_NOMEMORY) is in wGMError
* if wGMError doesn't contain a previous error.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_NOMEMORY
* GM_OVERFLOW
* GM_UNDERFLOW
* GM_DIV0
* GM_INVALIDID
*
* AUTHOR
* Jared Levy 05-JAN-1987 17:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *DivideDecimalAndRound(dst,src1,src2,nid)
DEC *dst;
DEC *src1,*src2;
int nid;
{
int i;
_MacStart(GM_DDIVR);
_MacInVarD(src1);
_MacInVarD(src2);
_MacOutVarD(dst);
if ((nid > GM_MAXID) || (nid < GM_MINID)){
_MacErr(GM_INVALIDID);
_MacRet (GM_NULL);
}
if (_MacIsDecZ(src2)) {
_MacErr(GM_DIV0);
_MacRet(GM_NULL);
}
i = _DivRndDec80Bit(dst, src1, src2, nid);
/* check if number can fit into 64 bits (no shifting allowed) */
if (!((dst->dc.msd == 0) && (dst->dc.sl[3] < 32768L)))
i = GM_OVERFLOW;
if (i != GM_SUCCESS) {
_MacErr(i);
if (i != GM_UNDERFLOW) {
_MacRet(GM_NULL);
}
}
_MacRet(dst);
}

74
gfm/ddivt.c Executable file
View File

@ -0,0 +1,74 @@
/* DEC *DivideDecimalAndTruncate(dst,src1,src2,nid);
*
* ARGUMENT
* DEC *dst;
* DEC *src1,*src2;
* int nid;
*
* DESCRIPTION
* Divides src1 by src2, storing the result in dst. The quotient is
* calculated to nid decimal places.
*
* RETURNS
* Returns pointer to dst if successful, otherwise a GM_NULL. The
* type error (GM_OVERFLOW, GM_UNDERFLOW, GM_NOMEMORY) is in wGMError
* if wGMError doesn't contain a previous error.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
* GM_UNDERFLOW
* GM_DIV0
* GM_INVALIDID
*
* AUTHOR
* Jared Levy 05-JAN-1987 17:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *DivideDecimalAndTruncate(dst,src1,src2,nid)
DEC *dst;
DEC *src1,*src2;
int nid;
{
int i;
_MacStart(GM_DDIVT);
_MacInVarD(src1);
_MacInVarD(src2);
_MacOutVarD(dst);
if ((nid > GM_MAXID) || (nid < GM_MINID)){
_MacErr(GM_INVALIDID);
_MacRet (GM_NULL);
}
if (_MacIsDecZ(src2)) {
_MacErr(GM_DIV0);
_MacRet(GM_NULL);
}
i = _DivTrnDec80Bit(dst, src1, src2, nid);
/* check if number can fit into 64 bits (no shifting allowed) */
if (!((dst->dc.msd == 0) && (dst->dc.sl[3] < 32768L)))
i = GM_OVERFLOW;
if (i != GM_SUCCESS) {
_MacErr(i);
if (i != GM_UNDERFLOW) {
_MacRet(GM_NULL);
}
}
_MacRet(dst);
}

151
gfm/ddix.c Executable file
View File

@ -0,0 +1,151 @@
/* int _DivDec80Bit(pDst,pSrc1,pSrc2);
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc1,pSrc2;
*
* DESCRIPTION
* Divides pDst = pSrc1 / pSrc2.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns GM_SUCCESS if successful, otherwise the error code.
* wGMError is not changed.
*
* AUTHOR
* Jared Levy 05-JAN-1987 17:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int _DivDec80Bit(c,a,b)
DEC *c;
DEC *a,*b;
{
register int i,t;
int maxp, p=0, mag2a, mag2b;
unsigned SHORT an[14], bn[6], *cn, ad[5], as[14];
/* check that b is nonzero */
if (_MacIsDecZ(b))
return(GM_DIV0);
/* check whether scr1 is zero */
if (_MacIsDecZ(a)) {
_MacDCopy(c,a);
return(GM_SUCCESS);
}
/* sets c = a / b,
where a and b are positive DEC numbers, and the result is stored in c */
bn[0]=b->dc.sl[0];
bn[1]=b->dc.sl[1];
bn[2]=b->dc.sl[2];
bn[3]=b->dc.sl[3];
bn[4]=b->dc.msd;
bn[5]=0;
cn = c->dc.sl;
an[0]=a->dc.sl[0];
an[1]=a->dc.sl[1];
an[2]=a->dc.sl[2];
an[3]=a->dc.sl[3];
an[4]=a->dc.msd;
an[5] = 0;
an[6] = 0;
an[7] = 0;
an[8] = 0;
an[9] = 0;
an[10]= 0;
an[11]= 0;
maxp = GM_IMAXID - (a->dc.id - b->dc.id);
if (maxp > 0) {
/* The following code uses up most of the time involved in divisions.
It starts with two 64-bit number integers an and bh, both positive,
along with an integer maxp. Two values are returned: a nonnegative
integer p and a 160-bit number as = an * 10^p. p is the largest number
satisfying the conditions (1) as < 2^160,
(2) the highest 80 bits of as are less than bh
(3) p <= maxp.
*/
i = 4;
while (an[i] == 0)
i--;
mag2a = 16 * i;
t = an[i]>>1;
while (t) {
t=t>>1;
mag2a++;
}
i = 4;
while ((bn[i] == 0) && (i>0))
i--;
mag2b = 16 * i;
t = bn[i]>>1;
while (t) {
t=t>>1;
mag2b++;
}
p = (78 + mag2b - mag2a) * 3 / 10;
if (p>maxp)
p=maxp;
if (p != 0)
_MulUnsArrByPwrOf10(an,p,10);
if (p != maxp) {
for(i=0; i<14; i++) {
as[i] = an[i];
}
i = _MulUnsArrByPwrOf10(as,1,10);
ad[0]=as[5];
ad[1]=as[6];
ad[2]=as[7];
ad[3]=as[8];
ad[4]=as[9];
_DoubleUnsArr(ad, 5);
if (as[4]&0x8000)
ad[0]=ad[0]+1;
if ((i == GM_SUCCESS) &&
(_CompareUnsArr(ad,bn,5) == -1)) {
p++;
for(i=0; i<10; i++)
an[i] = as[i];
}
}
/* p != maxp */
} /* maxp > 0 */
_DivUns10ArrByUns5Arr(cn,an,bn);
/* adjust implied decimal to correct value */
i = a->dc.id - b->dc.id + p;
if (i<GM_IMINID)
return(GM_OVERFLOW);
c->dc.id = i;
/* if the signs of the sources are different, c=-c */
c->dc.attr = (a->dc.attr^b->dc.attr);
return(GM_SUCCESS);
}

57
gfm/ddixf.c Executable file
View File

@ -0,0 +1,57 @@
/* int _DivDecFast(pDst,pSrc1,pSrc2);
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc1,pSrc2;
*
* DESCRIPTION
* Divides pDst = pSrc1 / pSrc2, to 64 bits of accuracy.
* This code is about 1/3 faster than ddix.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns GM_SUCCESS if successful, otherwise the error code.
* wGMError is not changed.
*
* AUTHOR
* Jared Levy 05-JAN-1987 17:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int _DivProcFast();
int _DivDecFast(pDst,pSrc1,pSrc2)
DEC *pDst;
DEC *pSrc1,*pSrc2;
{
/* check that pSrc2 is nonzero */
if (_MacIsDecZ(pSrc2))
return(GM_DIV0);
/* check whether scr1 is zero */
if (_MacIsDecZ(pSrc1)) {
_MacDCopy(pDst, pSrc1);
return(GM_SUCCESS);
}
if (_DivProcFast(pDst,pSrc1,pSrc2) != GM_SUCCESS)
return(GM_OVERFLOW);
/* if quotient is zero, an underflow has occured */
if (_MacIsDecZ(pDst))
return(GM_UNDERFLOW);
/* if the signs of the sources are different, pDst=-pDst */
pDst->dc.attr=pSrc1->dc.attr^pSrc2->dc.attr;
return(GM_SUCCESS);
}

63
gfm/ddixr.c Executable file
View File

@ -0,0 +1,63 @@
/* int _DivRndDec80Bit(pDst,pSrc1,pSrc2,wID);
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc1,pSrc2;
* int wID;
*
* DESCRIPTION
* Divides pDst = pSrc1 / pSrc2.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns GM_SUCCESS if successful, otherwise the error code.
* wGMError is not changed.
*
* AUTHOR
* Jared Levy 05-JAN-1987 17:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int _DivRndDec80Bit(pDst,pSrc1,pSrc2,wID)
DEC *pDst;
DEC *pSrc1,*pSrc2;
int wID;
{
int i;
unsigned SHORT s1[14], s2[11]; /* need extra memory */
/* check whether scr1 is zero */
if (_MacIsDecZ(pSrc1)) {
_MacDZero(pDst);
pDst->dc.id = wID;
return(GM_SUCCESS);
}
for(i=0;i<5;i++) {
s1[i]=pSrc1->dc.sl[i];
s2[i]=pSrc2->dc.sl[i];
}
s2[5]=0;
if(_DivProcRnd(pDst,s1,s2,pSrc1->dc.id,pSrc2->dc.id,
wID) != GM_SUCCESS)
return(GM_OVERFLOW);
/* if quotient is zero, an underflow has occured */
if (_MacIsDecZ(pDst))
return(GM_UNDERFLOW);
/* if the signs of the sources are different, pDst=-pDst */
pDst->dc.attr = (pSrc1->dc.attr^pSrc2->dc.attr);
return(GM_SUCCESS);
}

67
gfm/ddixt.c Executable file
View File

@ -0,0 +1,67 @@
/* int _DivTrnDec80Bit(pDst,pSrc1,pSrc2,wID);
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc1,pSrc2;
* int wID;
*
* DESCRIPTION
* Divides pDst = pSrc1 / pSrc2, truncating result to wId decimal places.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns GM_SUCCESS if successful, otherwise the error code.
* wGMError is not changed.
*
* AUTHOR
* Jared Levy 05-JAN-1987 17:30
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int _DivTrnDec80Bit(pDst,pSrc1,pSrc2,wID)
DEC *pDst;
DEC *pSrc1,*pSrc2;
int wID;
{
int i;
unsigned SHORT s1[14], s2[12]; /* need extra memory */
/* check that pSrc2 is nonzero */
if (_MacIsDecZ(pSrc2))
return(GM_DIV0);
/* check whether scr1 is zero */
if (_MacIsDecZ(pSrc1)) {
_MacDZero(pDst);
pDst->dc.id = wID;
return(GM_SUCCESS);
}
for(i=0;i<5;i++) {
s1[i]=pSrc1->dc.sl[i];
s2[i]=pSrc2->dc.sl[i];
}
s2[5]=0;
if(_DivProcTrn(pDst,s1,s2,pSrc1->dc.id,pSrc2->dc.id,
wID) != GM_SUCCESS)
return(GM_OVERFLOW);
/* if quotient is zero, an underflow has occured */
if (_MacIsDecZ(pDst))
return(GM_UNDERFLOW);
/* if the signs of the sources are different, pDst=-pDst */
pDst->dc.attr = (pSrc1->dc.attr^pSrc2->dc.attr);
return(GM_SUCCESS);
}

55
gfm/deltrz.c Executable file
View File

@ -0,0 +1,55 @@
/* DEC *DeleteTrailingZeroes(pDst, pSrc)
*
* ARGUMENT
* DEC *pSrc;
* DEC *pDst;
*
* DESCRIPTION
* Changes the interal representation of pSrc without changing its value
* by removing any trailing zeroes, if possible, and storing the result in
* pDst.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* None.
*
* AUTHOR
* Jared Levy
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *DeleteTrailingZeroes(pDst, pSrc)
DEC *pSrc;
DEC *pDst;
{
DEC dTemp, *pTemp=&dTemp;
unsigned i=0;
_MacStart(GM_DELTRZ);
_MacInVarD(pSrc);
_MacOutVarD(pDst);
_MacDCopy(pTemp, pSrc);
while ((i==0) && (pTemp->dc.id>0)) {
_MacDCopy(pDst, pTemp);
i = _DivUnsArrByUns(pTemp->dc.sl, 10, 5);
pTemp->dc.id--;
}
if (i==0)
_MacDCopy(pDst,pTemp);
_MacRet(pDst);
}

26
gfm/demo01.c Executable file
View File

@ -0,0 +1,26 @@
#include <stdio.h>
#include "gm.h"
void main(void);
void main()
{
DEC da, *a=&da, db, *b=&db, dc, *c=&dc;
char str[30];
ZeroDecimal(a);
ZeroDecimal(b);
ZeroDecimal(c);
printf(" First number: ");
scanf("%s", str);
ConvAsciiToDecimal(a,str);
printf("Second number: ");
scanf("%s", str);
ConvAsciiToDecimal(b,str);
MultiplyDecimalAndRound(c, a, b, 2);
ConvDecimalToAscii(str,c);
printf("The product rounded to 2 decimal places is %s\n",str);
}

22
gfm/demo02.c Executable file
View File

@ -0,0 +1,22 @@
#include <stdio.h>
#include "gm.h"
void main(void);
void main()
{
DEC da, *a=&da, db, *b=&db, dc, *c=&dc;
ZeroDecimal(a);
ZeroDecimal(b);
ZeroDecimal(c);
printf(" First number: ");
dscanf("%t", a);
printf("Second number: ");
dscanf("%t", b);
MultiplyDecimalAndRound(c, a, b, 2);
dprintf("The product rounded to 2 decimal places is %t\n",c);
}

18
gfm/demo03.c Executable file
View File

@ -0,0 +1,18 @@
#include <stdio.h>
#include "gm.h"
void main()
{
DEC da, *a=&da, db, *b=&db;
DEC *f;
char s[30];
do {
printf("Type a number: ");
scanf("%s",s);
f = ConvAsciiToDecimal(a,s);
} while (f == GM_NULL);
CopyDecimal(b,a);
ConvDecimalToAscii(s,b);
printf("You typed a %s\n",s);
}

23
gfm/demo04.c Executable file
View File

@ -0,0 +1,23 @@
#include <stdio.h>
#include "gm.h"
void main(void);
void main()
{
DEC da, *a=&da, db, *b=&db, dc, *c=&dc;
DEC dt, *t=&dt, dx, *x=&dx, *p;
char str[30];
ConvAsciiToDecimal(a, "13.22");
ConvAsciiToDecimal(b, "34.89");
ConvAsciiToDecimal(c, "1.0625");
p = MultiplyDecimalAndRound(x, c, AddDecimal(t, a, b), 2);
if (p) {
ConvDecimalToAscii(str, x);
printf("The result is %s\n", str);
}
else
printf("The computation failed.\n");
}

24
gfm/demo05.c Executable file
View File

@ -0,0 +1,24 @@
#include <stdio.h>
#include "gm.h"
void main(void);
void main()
{
DEC x[1];
char s[30];
ConvAsciiToDecimal(x, "12,345.6");
ConvDecimalToAscii(s, x);
printf("ConvDecimalToAscii: %s\n", s);
ConvDecimalToAsciiRound(s, x, 2);
printf("ConvDecimalToAsciiRound: %s\n", s);
ConvDecimalToAsciiComma(s, x);
printf("ConvDecimalToAsciiComma: %s\n", s);
ConvDecimalToAsciiCommaRound(s, x, 2);
printf("ConvDecimalToAsciiCommaRound: %s\n", s);
ConvDecimalToScientific(s, x, -1);
printf("ConvDecimalToScientific: %s\n", s);
ConvDecimalToEngineering(s, x, -1);
printf("ConvDecimalToEngineering: %s\n", s);
}

43
gfm/demo06.c Executable file
View File

@ -0,0 +1,43 @@
#include <stdio.h>
#include "gm.h"
void printres(char *,DEC *);
void main(void);
void main()
{
DEC *x, *y, *p;
x = AllocateDecimal();
y = AllocateDecimal();
p = ConvAsciiToDecimal(x, "19.88");
printres("x = ", p);
p = AbsoluteDecimal(y, x);
printres("abs(x) = ", p);
p = ChangeSignDecimal(y, x);
printres("-x = ", p);
p = FractionDecimal(y, x);
printres("fract(x) = ", p);
p = IntegerPartDecimal(y, x);
printres("int(x) = ", p);
p = SquareRootDecimal(y, x);
printres("sqrt(x) = ", p);
FreeDecimal(x);
FreeDecimal(y);
}
void printres(str, pd)
char *str;
DEC *pd;
{
char sd[22];
printf("%12s", str);
if (pd) {
ConvDecimalToAscii(sd, pd);
printf("%s\n", sd);
}
else
printf("undefined\n");
}

56
gfm/demo07.c Executable file
View File

@ -0,0 +1,56 @@
#include <stdio.h>
#include "gm.h"
void printres(char *,DEC *);
void main(void);
void main()
{
DECP x, y, z;
DEC *p;
char s[40];
do {
printf(" First number (x) : ");
scanf("%s", s);
p = ConvAsciiToDecimal(x, s);
} while (!p);
do {
printf("Second number (y) : ");
scanf("%s", s);
p = ConvAsciiToDecimal(y, s);
} while (!p);
printres("x = ", x);
printres("y = ", y);
p = AddDecimal(z, x, y);
printres("x + y = ", p);
p = SubtractDecimal(z, x, y);
printres("x - y = ", p);
p = MultiplyDecimal(z, x, y);
printres("x * y = ", p);
p = DivideDecimal(z, x, y);
printres("x / y = ", p);
p = MultiplyDecimalAndRound(z, x, y, 2);
printres("x * y (rounded) = ", p);
p = MultiplyDecimalAndTruncate(z, x, y, 2);
printres("x * y (truncated) = ", p);
p = DivideDecimalAndRound(z, x, y, 2);
printres("x / y (rounded) = ", p);
p = DivideDecimalAndTruncate(z, x, y, 2);
printres("x / y (truncated) = ", p);
}
void printres(str, pd)
char *str;
DEC *pd;
{
char sd[22];
printf("%20s", str);
if (pd) {
ConvDecimalToAscii(sd, pd);
printf("%s\n", sd);
}
else
printf("undefined\n");
}

36
gfm/demo08.c Executable file
View File

@ -0,0 +1,36 @@
#include <stdio.h>
#include "gm.h"
void main(void);
void main()
{
DEC da, *a=&da, db, *b=&db;
DEC *f;
char s[30];
int prec;
do {
printf("Type a number: ");
scanf("%s",s);
f = ConvAsciiToDecimal(a,s);
} while (f == GM_NULL);
printf("Round to how many decimal places? ");
scanf("%d", &prec);
f = RoundDecimal(b, a, prec);
if (f) {
ConvDecimalToAscii(s, b);
printf(" Rounding yields %s\n", s);
}
else
printf("Rounding failed\n");
f = TruncateDecimal(b, a, prec);
if (f) {
ConvDecimalToAscii(s, b);
printf("Truncation yields %s\n", s);
}
else
printf("Truncating failed\n");
}

26
gfm/demo09.c Executable file
View File

@ -0,0 +1,26 @@
#include <stdio.h>
#include "gm.h"
void main(void);
void main()
{
char *path="tmpfile";
char buffer[40];
FILE *fil;
DEC da, *a=&da;
ConvAsciiToDecimal(a, "3.14159");
dprintf(" dprintf outputs %t\n", a);
dsprintf(buffer, "%t", a);
printf("dsprintf outputs %s\n", buffer);
fil = fopen(path, "w");
dfprintf(fil, "%t", a);
fclose(fil);
fil = fopen(path, "r");
fscanf(fil, "%s", buffer);
fclose(fil);
printf("dfprintf outputs %s\n", buffer);
}

11
gfm/demo10.c Executable file
View File

@ -0,0 +1,11 @@
#include <stdio.h>
#include "gm.h"
void main(void);
void main()
{
DECP x;
double f=98.76;
ConvDoubleToDecimalRound(x, f, 2);
dprintf("The double %7.2lf equals the DEC %t\n", f, x);
}

16
gfm/demo11.c Executable file
View File

@ -0,0 +1,16 @@
#include <stdio.h>
#include "gm.h"
void main(void);
void main()
{
DEC da, *a=&da;
int i;
do {
printf("Type a number: ");
i = dscanf("%t",a);
} while (i<1);
dprintf("You typed a %t\n",a);
}

44
gfm/demo12.c Executable file
View File

@ -0,0 +1,44 @@
#include <stdio.h>
#include "gm.h"
void SmartScan(char *,DEC *);
void main(void);
void main()
{
DECP x;
SmartScan("Type a number: ", x);
PrintDecimal("You typed a %t\n", x);
}
void SmartScan(s, pd)
char *s;
DEC *pd;
{
bool done;
int i;
if (!pd) {
printf("Error: null DEC pointer\n");
return;
}
ClearMathError();
done=FALSE;
while (!done) {
printf("%s",s);
ScanDecimal("%t",pd);
i = ReturnMathErrAndClear();
if (i==GM_SUCCESS)
done=TRUE;
if (i==GM_CNVRW) {
done=TRUE;
printf("Warning: Digit loss due to rounding\n");
}
if (i==GM_CNVRE)
printf("Error: Number out of range\n");
if (i==GM_NAN)
printf("Error: Not a number\n");
}
return;
}

34
gfm/demo13.c Executable file
View File

@ -0,0 +1,34 @@
#include <stdio.h>
#include "gm.h"
void ErrorHandler(int,int);
void main(void);
void ErrorHandler(code,ref)
int code,ref;
{
char serr[15],sfun[32];
ErrorName(serr, code);
FunctionName(sfun, ref);
printf("%s error in function %s\n",serr,sfun);
}
void main()
{
DEC da, *a=&da, db, *b=&db, dc, *c=&dc, *p;
SetMathErrVector(ErrorHandler);
ZeroDecimal(a);
ZeroDecimal(b);
ZeroDecimal(c);
dprintf("First number: ");
dscanf("%.2t",a);
dprintf("Second number: ");
dscanf("%.2t",b);
p = DivideDecimalAndRound(c,a,b,2);
if (p)
dprintf("%t / %t = %t\n",a,b,c);
else
dprintf("Division failed.\n");
}

18
gfm/demo14.c Executable file
View File

@ -0,0 +1,18 @@
#include <stdio.h>
#include "gm.h"
void main(void);
void main()
{
DEC *a[10];
int i;
for (i=0; i<10; i++)
a[i] = AllocateDecimal();
for (i=0; i<10; i++)
ConvIntToDecimal(a[i], i*i);
dprintf("%10s%10s\n","Element","Value");
for (i=0; i<10; i++)
dprintf("%10d%10t\n", i, a[i]);
for (i=0; i<10; i++)
FreeDecimal(a[i]);
}

39
gfm/demo15.c Executable file
View File

@ -0,0 +1,39 @@
#include <stdio.h>
#include "gm.h"
void main(void);
void main()
{
DEC *xarr[100], *yarr[100], *p;
DECP lina, linb, corr, gx, gy, px, py;
int n, i;
printf("Number of elements: ");
scanf("%d", &n);
AllocateDecimalArray(xarr, n);
AllocateDecimalArray(yarr, n);
for (i=0; i<n; i++) {
printf("X Element #%d: ",i);
dscanf("%t", xarr[i]);
printf("Y Element #%d: ",i);
dscanf("%t", yarr[i]);
}
p = LinearEstimate(corr, lina, linb, xarr, yarr, n);
if (p) {
dprintf("\nY = %t + %t * X\n", lina, linb);
dprintf("Correleation coefficient: %t\n", corr);
}
else
dprintf("\nLinearEstimate failed\n");
printf("\nGiven X value: ");
dscanf("%t", gx);
if (PredictY(py, gx))
dprintf("X = %t corresponds to Y = %t\n", gx, py);
printf("\nGiven Y value: ");
dscanf("%t", gy);
if (PredictX(px, gy))
dprintf("Y = %t corresponds to X = %t\n", gy, px);
}

65
gfm/demo16.c Executable file
View File

@ -0,0 +1,65 @@
#include <stdio.h>
#include "gm.h"
void getdec(char *,DEC *);
void main(void);
void main()
{
int choice, opt, nper=0, diy=365;
DECP pv, intr, intamt;
DEC *p;
printf("Simple interest computation\n");
printf("Variable to solve for --\n");
printf(" 1) Number of days\n 2) Interest rate\n");
printf(" 3) Principal\n 4) Accrued interest\n");
printf("Your choice: ");
scanf("%d", &choice);
if (choice == 1)
opt = GM_N;
if (choice == 2)
opt = GM_I;
if (choice == 3)
opt = GM_PV;
if (choice == 4)
opt = GM_INTR;
if (opt != GM_N) {
printf("Number of days: ");
scanf("%d", &nper);
}
if (opt != GM_I)
getdec("Percentage annual interest rate: ", intr);
if (opt != GM_PV)
getdec("Principal: ", pv);
if (opt != GM_INTR)
getdec("Accrued interest: ", intamt);
dprintf("Number of days in year (360 or 365): ");
dscanf("%d", &diy);
if (diy == 360)
p = simp360(&nper, intr, pv, intamt, opt);
else
p = simp365(&nper, intr, pv, intamt, opt);
if (opt==GM_N)
dprintf("The result is %d\n",nper);
else {
if (p)
dprintf("The result is %v\n",p);
else
dprintf("Simple interest failed\n");
}
}
void getdec(str, x)
char *str;
DEC *x;
{
int i;
do {
printf("%s", str);
i = dscanf("%t", x);
} while (i<1);
}

44
gfm/demo17.c Executable file
View File

@ -0,0 +1,44 @@
#include <stdio.h>
#include "gm.h"
void getdec(char *,DEC *);
void main(void);
void main()
{
int nper, nyear, opt, begend;
DECP pv, pmt, fv, intr, aintr;
DEC *p;
printf("Monthly payment computation\n");
getdec("Purchase price: ", pv);
getdec("Percentage annual interest rate: ", aintr);
printf("Length of loan (years): ");
dscanf("%d", &nyear);
nper = nyear * 12;
ZeroDecimal(fv);
DivideDecimalByInt(intr, aintr, 12);
opt = GM_PMT;
begend = GM_END;
p = CompoundInterest(&nper, intr, pv, pmt, fv, begend, opt);
if (p) {
AbsoluteDecimal(pmt, pmt);
dprintf("The monthly payment is %v\n", pmt);
}
else
dprintf("CompoundInterest failed\n");
}
void getdec(str, x)
char *str;
DEC *x;
{
int i;
do {
printf("%s", str);
i = dscanf("%t", x);
} while (i<1);
}

53
gfm/demo18.c Executable file
View File

@ -0,0 +1,53 @@
#include <stdio.h>
#include "gm.h"
void getdec(char *,DEC *);
void main(void);
static DEC *payintr[500], *payprin[500], *balance[500];
void main()
{
int nper, nyear, begend, i;
DECP pv, pmt, intr, aintr;
extern DEC *payintr[500], *payprin[500], *balance[500];
printf("Amortization schedule\n");
getdec("Amount of loan (positive): ", pv);
getdec("Percentage annual interest rate: ", aintr);
printf("Length of loan (years): ");
dscanf("%d", &nyear);
getdec("Monthly payment (positive): ", pmt);
nper = nyear * 12;
DivideDecimalByInt(intr, aintr, 12);
begend = GM_END;
AllocateDecimalArray(payintr, nper+1);
AllocateDecimalArray(payprin, nper+1);
AllocateDecimalArray(balance, nper+1);
AmortizeTable(payintr, payprin, balance, intr,
pv, pmt, begend, nper);
printf("%15s%20s%20s%20s\n", "Payment #", "Interest",
"Principal", "Balance");
for (i=1; i<=nper; i++)
dprintf("%15d%20v%20v%20v\n", i, payintr[i],
payprin[i], balance[i]);
FreeDecimalArray(payintr);
FreeDecimalArray(payprin);
FreeDecimalArray(balance);
}
void getdec(str, x)
char *str;
DEC *x;
{
int i;
do {
printf("%s", str);
i = dscanf("%t", x);
} while (i<1);
}

46
gfm/demo19.c Executable file
View File

@ -0,0 +1,46 @@
#include <stdio.h>
#include "gm.h"
void getdec(char *,DEC *);
void main(void);
void main()
{
DEC book[1], salv[1], partial[1];
DEC *depr[50], *remval[50];
int life, i;
printf("Sum of years digits depreciation\n");
getdec("Book value: ", book);
getdec("Salvage value: ", salv);
printf("Lifetime of asset (years): ");
dscanf("%d", &life);
ZeroDecimal(partial);
AllocateDecimalArray(depr, life+1);
AllocateDecimalArray(remval, life+1);
DepreciateSumOfYearsTable(depr, remval, book,
salv, life, partial);
printf("%20s%20s%20s\n", "Year #",
"Depreciation", "Remaining Value");
for (i=1; i<=life; i++)
dprintf("%20d%20v%20v\n", i,
depr[i], remval[i]);
FreeDecimalArray(depr);
FreeDecimalArray(remval);
}
void getdec(str, x)
char *str;
DEC *x;
{
int i;
do {
printf("%s", str);
i = dscanf("%t", x);
} while (i<1);
}

77
gfm/dexp.c Executable file
View File

@ -0,0 +1,77 @@
/* DEC *AntiLogEDecimal(pDst,pSrc)
*
* ARGUMENT
* DEC *pDst;
* DEC *pSrc;
*
* DESCRIPTION
* Sets pDst = e^pSrc;
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns pointer to pDst if successful, otherwise a GM_NULL. The
* type error (GM_OVERFLOW, GM_UNDERFLOW, GM_NOMEMORY) is in wGMError
* if wGMError didn't contain a previous error on entry.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_OVERFLOW
* GM_UNDERFLOW
*
* AUTHOR
* Jared Levy Aug 7, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *AntiLogEDecimal(pDst,pSrc)
DEC *pDst;
DEC *pSrc;
{
int i;
DEC *pa;
_MacStart(GM_DEXP);
_MacInVarD(pSrc);
_MacOutVarD(pDst);
if((pSrc->dc.id == 0) && ((pSrc->dc.msd == 0) &&
(pSrc->ls.lsl[1] == 0L) && (pSrc->dc.sl[1] == 0))
&& (!(pSrc->dc.sl[0] & 0x8000))) {
pa = &decE; /* points to constant 'e' */
_MacDCopy(pDst,pa);
i = _IntPwrDec80Bit(pDst,pDst,ConvDecimalToInt(pSrc));
if(i != GM_SUCCESS) {
_MacErr(i);
_MacRet(GM_NULL);
}
}
else {
i = _ExpDec80Bit(pDst, pSrc);
if (i == GM_OVERFLOW) {
_MacErr(i);
_MacRet(GM_NULL);
}
}
/* reduce from 80-bit back to 64-bit */
if(_Sq5UnsTo4Uns(pDst) != GM_SUCCESS) {
_MacErr(GM_OVERFLOW);
_MacRet(GM_NULL);
}
if (_MacIsDecZ(pDst)) {
_MacErr(GM_UNDERFLOW);
}
_MacRet(pDst);
}

113
gfm/dexx.c Executable file
View File

@ -0,0 +1,113 @@
/* int _ExpDec80Bit(pDst,pSrc)
*
* ARGUMENT
* DEC *pDst, *pSrc;
*
* DESCRIPTION
* Calculates e^pSrc, stores result in pDst.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* GM_SUCCESS if calculation is successful,
* otherwise the error code (which could be underflow)
*
* ALGORITHM
* pSrc = a * ln 2 + b |b| < (ln 2) / 2
* e^pSrc = (2^a) * (e^b)
* Using the Taylor series,
* e^b = 1 + b + (b^2)/2! + (b^3)/3! + ...
*
* AUTHOR
* Jared Levy April 7, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int _ExpDec80Bit(pDst,pSrc)
DEC *pDst, *pSrc;
{
int a, i;
DEC da, dpow2, db, dt, dfact, dterm;
DEC *pow2, *b, *fact, *pt, *term;
if (CompareDecimal(pSrc,&decMaxExp) == 1) {
return(GM_OVERFLOW);
}
if (CompareDecimal(pSrc,&decMinExp) == -1) {
_MacDZero(pDst);
return(GM_UNDERFLOW);
}
/* calculate a = pSrc * (1/(ln 2)) */
(void) _MulDec80Bit(&da, pSrc, &decReciprocalOfLn2);
(void) _ScaleDec80Bit(&da,&da,0);
a = ConvDecimalToInt(&da);
/* calculate b = pSrc - a * ln 2 */
b=&db;
if (a == 0) {
_MacDCopy(b,pSrc);
}
else {
(void) _MulDec80Bit(&dt, &da, &decLn2);
(void) _SubDec80Bit(b, pSrc, &dt);
}
/* calculate pSrc = (2^a) * (e^b) */
fact = &dfact;
pt = &decOne;
term = &dterm;
_MacDCopy(fact,pt);
_MacDCopy(pDst,pt);
_AddDec80Bit(pDst, pDst, b);
_MacDCopy(term, b);
do {
/* calulate next term */
fact->dc.sl[0]++;
(void) _MulDec80Bit(term, b, term);
(void) _DivRndDec80Bit(term, term, fact, 23);
/* add term to series */
(void) _AddDec80Bit(pDst, pDst, term);
/* calc next factorial term in divisor */
} while (!(_MacIsDecZ(term)));
if (a>0) {
pow2 = &dpow2;
/*
* I used to use the _MacDZero statement here, but Lattice C 6.0
* pointed out that it had a single redundant line in the
* macro, so I expanded it and remove the redundant line.
* _MacDZero(pow2);
*/
pow2->dc.attr=0;
pow2->ls.lsl[0]=0;
pow2->ls.lsl[1]=0;
pow2->dc.msd=0;
pow2->dc.id = 0;
pow2->dc.sl[a/16] = 1 << (a % 16);
i =_MulDec80Bit(pDst, pDst, pow2);
return(i);
}
while (a<0) {
_HalveUnsArr(pDst->dc.sl, 5);
a++;
}
if (_MacIsDecZ(pDst))
return(GM_UNDERFLOW);
return(GM_SUCCESS);
}

61
gfm/dfact.c Executable file
View File

@ -0,0 +1,61 @@
/* DEC *Factorial(pDst, n)
*
* ARGUMENT
* DEC *pDst;
* unsigned n;
*
* DESCRIPTION
* Sets pDst = n!
*
* SIDE EFFECTS
* None.
*
* RETURNS
* pDst if successful, GM_NULL otherwise
*
* POSSIBLE ERRORS
* GM_NOMEMORY
* GM_OVERFLOW (if n > 20)
*
* AUTHOR
* Jared Levy
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *Factorial(pDst, n)
DEC *pDst;
unsigned n;
{
DEC dmult, *mult = &dmult;
unsigned i;
_MacStart(GM_DFACT);
_MacOutVarD(pDst);
/* check for overflow */
if (n > 20) {
_MacErr(GM_OVERFLOW);
_MacRet(GM_NULL);
}
/* do calculations */
_MacDCopy(pDst, &decOne);
_MacDCopy(mult, &decOne);
for (i=2; i<=n; i++) {
mult->dc.sl[0] = i;
_MulDec80Bit(pDst, pDst, mult);
}
/* pDst fits into 64 bits */
_MacRet(pDst);
}

71
gfm/dfprintf.c Executable file
View File

@ -0,0 +1,71 @@
/* int FilePrintDecimal(stream, fmt, arg,)
*
* ARGUMENT
* FILE *stream;
* char *fmt;
* (?) arg;
*
* DESCRIPTION
* Prints out arguments, which may include DEC structures, to a file,
* according to the format string fmt. The function converts the DEC's
* to strings and calls fprintf.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* The number of characters printed, the return from fprintf.
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_NULLSTRING
* GM_INVALIDID
* GM_CNVRW
* GM_EOF
*
* AUTHOR
* Jared Levy
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int FilePrintDecimal(stream,fmt)
FILE *stream;
char *fmt;
{
char **outval, buffer[256];
int i;
_MacStart(GM_DFPRINTF);
if (!fmt) {
_MacErr(GM_NULLPOINTER);
_MacRet(0);
}
outval = &fmt;
/* print the output */
dsprintf(buffer, fmt,
outval[1], outval[2], outval[3], outval[4], outval[5],
outval[6], outval[7], outval[8], outval[9], outval[10]
#ifndef _LDATA
,outval[11], outval[12], outval[13], outval[14], outval[15],
outval[16], outval[17], outval[18], outval[19], outval[20]
#endif
);
i = fprintf(stream, "%s", buffer);
if (i==EOF)
_MacErr(GM_EOF);
_MacRet(i);
}

45
gfm/dfract.c Executable file
View File

@ -0,0 +1,45 @@
/* DEC *FractionDecimal(pDst,pSrc)
*
* ARGUMENT
* DEC* pDst ptr to the destination DEC structure.
* DEC* pSrc ptr to the source DEC structure.
*
* DESCRIPTION
* Sets pDst to the fractional part of pSrc.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns a pointer to the DEC structure unless pSrc is null.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Andy Anderson 13-JAN-1987 17:20
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *FractionDecimal(pDst,pSrc)
DEC *pDst,*pSrc;
{
DEC dtemp, *temp=&dtemp;
_MacStart(GM_DFRACT);
_MacInVarD(pSrc);
_MacOutVarD(pDst);
(void) _TruncateDec80Bit(temp, pSrc, 0);
(void) _SubDec80Bit(pDst, pSrc, temp);
_MacRet(pDst);
}

54
gfm/dfree.c Executable file
View File

@ -0,0 +1,54 @@
/* void FreeDecimal(pSrc1)
*
* ARGUMENT
* pSrc1 is a ptr to the source DEC structure.
*
* DESCRIPTION
* Returns storage to DOS via free().
*
* SIDE EFFECTS
* Does NOT CHECK to see if spaces was allocated via malloc().
* Therefore, DOS will lock up cause cold reboot if unallocated
* space is freed
*
* RETURNS
* None.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Andy Anderson 17-JAN-1987 14:35
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include <malloc.h>
#include "gm.h"
#include "gmsystem.h"
void FreeDecimal(pSrc1)
DEC *pSrc1;
{
_MacStart(GM_DFREE);
/* Can't free null pointers */
if(!pSrc1) {
_MacErr(GM_NULLPOINTER);
_MacRetV;
}
/* But we'll free him a DEC if possible */
#ifdef LATTICE
free((char *) pSrc1);
#else
free((char *) pSrc1);
#endif
_MacRetV;
}

64
gfm/dfscanf.c Executable file
View File

@ -0,0 +1,64 @@
/* int FileScanDecimal(fFile, sFmt, arg,)
*
* ARGUMENT
* FILE *fFile;
* char *sFmt;
* (?) arg;
*
* DESCRIPTION
* Scans arguments, which may include DEC structures,
* from a string, according
* to the format string sFmt. The function converts the DEC's to strings
* and calls scanf.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* The number of fields scanned, the return from scanf.
*
* POSSIBLE ERRORS
* GM_NULLPOINTER
* GM_NULLSTRING
* GM_INVALIDID
* GM_CNVRW
* GM_CNVRE
* GM_NAN
* GM_EOF
*
* AUTHOR
* Jared Levy
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int FileScanDecimal(fFile,sFmt)
FILE *fFile;
char *sFmt;
{
int i;
char **pOutVal;
_MacStart(GM_DFSCANF);
pOutVal=&sFmt;
i=_ScanfAux(3, (char *) fFile, sFmt,
pOutVal[1], pOutVal[2], pOutVal[3], pOutVal[4], pOutVal[5],
pOutVal[6], pOutVal[7], pOutVal[8], pOutVal[9], pOutVal[10]
#ifndef _LDATA
,pOutVal[11], pOutVal[12], pOutVal[13], pOutVal[14], pOutVal[15],
pOutVal[16], pOutVal[17], pOutVal[18], pOutVal[19], pOutVal[20]
#endif
);
_MacRet(i);
}

129
gfm/dftod.c Executable file
View File

@ -0,0 +1,129 @@
/* DEC *ConvDoubleToDecimal( x, f)
*
* ARGUMENT
* DEC *x;
* double f;
*
* DESCRIPTION
* Converts a double to a DEC with maximum implied decimal. Uses
* eTwoTo32 (2^32), eTwoTo63 (2^63), and ergGMPowersOfTenDouble
* (powers of ten), all global double variables.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* The DEC if the conversion is successful, and GM_NULL otherwise.
*
* POSSIBLE ERROR CODES
*
* GM_NOMEMORY
* GM_CNVRE
*
* AUTHOR
* Jared Levy Feb. 9, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *ConvDoubleToDecimal( x, f)
DEC *x;
double f;
{
int nid;
mbool wfIsNeg=FALSE;
double g;
_MacStart(GM_DFTOD);
_MacOutVarD(x);
/* take absolute value of negative values */
if (f<0.0) {
wfIsNeg = TRUE;
f = -f;
}
/* f = 0 */
if (f == 0.0) {
_MacDZero(x);
_MacRet(x);
}
/* overflow & underflow (MAXID = 18, MINID = 0) */
if ((f>=eTwoTo63) || (f<.5e-18)) {
if (x)
_MacDZero(x);
_MacErr(GM_CNVRE);
_MacRet(GM_NULL);
}
/* take absolute value of negative values */
if (f<0.0) {
wfIsNeg = TRUE;
f = -f;
}
_MacDZero(x);
/* calculate implied decimal of DEC */
g = eTwoTo63/f;
nid = 0;
while ((nid <= 17) && (ergGMPowersOfTenDouble[nid+1] <= g))
nid++;
/* adjust by power of 10 */
f = f * ergGMPowersOfTenDouble[nid];
/* add .5 to round rather than truncate */
f+= 0.5;
/* change float to 64 bit integer */
if (f >= eTwoTo32 - 1) {
#ifdef ZORTECH
if ( (f / eTwoTo32) > eTwoTo31 ) {
x->ls.lsl[1] = (unsigned long) ((f / eTwoTo32) - eTwoTo31 );
x->ls.lsl[1] += (unsigned long) eTwoTo31;
} else
x->ls.lsl[1] = (unsigned long) (f / eTwoTo32);
#else
x->ls.lsl[1] = (unsigned long) (f / eTwoTo32);
#endif
g = (double) x->ls.lsl[1];
f-= g * eTwoTo32;
while (f<0.0) {
x->ls.lsl[1]--;
f+= eTwoTo32;
}
while (f>= eTwoTo32) {
x->ls.lsl[1]++;
f-= eTwoTo32;
}
}
else
x->ls.lsl[1] = 0;
#ifdef ZORTECH
if ( f > eTwoTo31 ) {
x->ls.lsl[0] = f - eTwoTo31;
x->ls.lsl[0] += (unsigned long) eTwoTo31;
} else
x->ls.lsl[0] = (unsigned long) f;
#else
x->ls.lsl[0] = (unsigned long) f;
#endif
x->ls.lid = nid;
x->dc.msd = 0; /* msd can't be set either */
if (wfIsNeg) {
_MacDChgs(x);
}
_MacRet(x);
}

123
gfm/dftodr.c Executable file
View File

@ -0,0 +1,123 @@
/* DEC *ConvDoubleToDecimalRound( x, f, nid)
*
* ARGUMENT
* DEC *x;
* double f;
* int nid;
*
* DESCRIPTION
* Converts a double to a DEC with implied decimal nid. Uses
* eTwoTo32 (2^32), eTwoTo63 (2^63), and ergGMPowersOfTenDouble
* (powers of ten), all global double variables.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* The DEC if the conversion is successful, and GM_NULL otherwise.
*
* POSSIBLE ERROR CODES
*
* GM_NOMEMORY
* GM_CNVRE
* GM_INVALIDID
*
* AUTHOR
* Jared Levy Feb. 9, 1987
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *ConvDoubleToDecimalRound( x, f, nid)
DEC *x;
double f;
int nid;
{
mbool wfIsNeg=FALSE;
double g;
_MacStart(GM_DFTODR);
if ((nid > GM_MAXID) || (nid < GM_MINID)) {
_MacErr(GM_INVALIDID);
_MacRet(GM_NULL);
}
_MacOutVarD(x);
/* f = 0 */
if (f == 0.0) {
_MacDZero(x);
_MacRet(x);
}
/* take absolute value of negative values */
if (f<0.0) {
wfIsNeg = TRUE;
f = -f;
}
/* adjust by power of 10 */
if (nid > 0) {
f*= ergGMPowersOfTenDouble[nid];
}
_MacDZero(x);
/* overflow and underflow */
if ((f>=eTwoTo63) || (f<0.5)) {
_MacErr(GM_CNVRE);
_MacRet(GM_NULL);
}
/* add .5 to round rather than truncate */
f+= 0.5;
/* change float to 64 bit integer */
if (f >= eTwoTo32-1) {
#ifdef ZORTECH
if ( (f / eTwoTo32) > eTwoTo31 ) {
x->ls.lsl[1] = (unsigned long) ((f / eTwoTo32) - eTwoTo31 );
x->ls.lsl[1] += (unsigned long) eTwoTo31;
} else
x->ls.lsl[1] = (unsigned long) (f / eTwoTo32);
#else
x->ls.lsl[1] = (unsigned long) (f / eTwoTo32);
#endif
g = (double) x->ls.lsl[1];
if (g<0.0)
g+= eTwoTo32;
f = f - g * eTwoTo32;
while (f<0.0) {
x->ls.lsl[1]--;
f+= eTwoTo32;
}
while (f>= eTwoTo32) {
x->ls.lsl[1]++;
f-= eTwoTo32;
}
}
#ifdef ZORTECH
if ( f > eTwoTo31 ) {
x->ls.lsl[0] = f - eTwoTo31;
x->ls.lsl[0] += (unsigned long) eTwoTo31;
} else
x->ls.lsl[0] = (unsigned long) f;
#else
x->ls.lsl[0] = (unsigned long) f;
#endif
x->ls.lid = nid;
if (wfIsNeg)
_MacDChgs(x);
_MacRet(x);
}

44
gfm/dint.c Executable file
View File

@ -0,0 +1,44 @@
/* DEC *IntegerPartDecimal(pDst,pSrc)
*
* ARGUMENT
* DEC* pDst ptr to the destination DEC structure.
* DEC* pSrc ptr to the source DEC structure.
*
* DESCRIPTION
* Sets pDst to the integer part of pSrc.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns a pointer to the DEC structure unless pSrc is null.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
* GM_NOMEMORY
*
* AUTHOR
* Andy Anderson 13-JAN-1987 17:20
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
DEC *IntegerPartDecimal(pDst,pSrc)
DEC *pDst,*pSrc;
{
_MacStart(GM_DINT);
_MacInVarD(pSrc);
_MacOutVarD(pDst);
(void) _TruncateDec80Bit(pDst, pSrc, 0);
_MacRet(pDst);
}

53
gfm/diseq.c Executable file
View File

@ -0,0 +1,53 @@
/* int IsDecimalEqual(pSrc1,pSrc2)
*
* ARGUMENT
* pSrc1 is a ptr to the source1 DEC structure.
* pSrc2 is a ptr to the source2 DEC structure.
*
* DESCRIPTION
* Compares pSrc1:pSrc2 and return TRUE if pSrc1==pSrc2.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns TRUE if scr1==scr2, FALSE if pSrc1 != pSrc2.
* However, returns GM_NULLPOINTER if pSrc1 or pSrc2 point to a null.
*
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Andy Anderson 14-JAN-1987 14:27
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int IsDecimalEqual(pSrc1,pSrc2)
DEC *pSrc1,*pSrc2;
{
int i;
_MacStart(GM_DISEQ);
i=CompareDecimal(pSrc1,pSrc2);
switch(i) {
case 0: {
_MacRet(TRUE);
}
case 1:
case -1: {
_MacRet(FALSE);
}
}
_MacRet(i);
}

52
gfm/disge.c Executable file
View File

@ -0,0 +1,52 @@
/* int IsDecimalGreaterOrEqual(pSrc1,pSrc2)
*
* ARGUMENT
* pSrc1 is a ptr to the source1 DEC structure.
* pSrc2 is a ptr to the source2 DEC structure.
*
* DESCRIPTION
* Compares pSrc1:pSrc2 and return TRUE if pSrc1>=pSrc2.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns TRUE if scr1>=scr2, FALSE if pSrc1 < pSrc2.
* However, returns GM_NULLPOINTER if pSrc1 or pSrc2 point to a null.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Andy Anderson 14-JAN-1987 14:27
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int IsDecimalGreaterOrEqual(pSrc1,pSrc2)
DEC *pSrc1,*pSrc2;
{
int i;
_MacStart(GM_DISGE);
i=CompareDecimal(pSrc1,pSrc2);
switch(i) {
case 0:
case 1: {
_MacRet(TRUE);
}
case -1: {
_MacRet(FALSE);
}
}
_MacRet(i);
}

52
gfm/disgt.c Executable file
View File

@ -0,0 +1,52 @@
/* int IsDecimalGreater(pSrc1,pSrc2)
*
* ARGUMENT
* pSrc1 is a ptr to the source1 DEC structure.
* pSrc2 is a ptr to the source2 DEC structure.
*
* DESCRIPTION
* Compares pSrc1:pSrc2 and return TRUE if pSrc1>pSrc2.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* Returns TRUE if scr1>scr2, FALSE if pSrc1 <= pSrc2.
* However, returns GM_NULLPOINTER if pSrc1 or pSrc2 point to a null.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Andy Anderson 22-APR-1987 14:27
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int IsDecimalGreater(pSrc1,pSrc2)
DEC *pSrc1,*pSrc2;
{
int i;
_MacStart(GM_DISGT);
i=CompareDecimal(pSrc1,pSrc2);
switch(i) {
case 1: {
_MacRet(TRUE);
}
case 0:
case -1: {
_MacRet(FALSE);
}
}
_MacRet(i);
}

47
gfm/disint.c Executable file
View File

@ -0,0 +1,47 @@
/* int IsDecimalInt(pSrc);
*
* ARGUMENT
* DEC *pSrc;
*
* DESCRIPTION
* Determines whether or not a DEC represents an integer value
* or decimal value.
*
* SIDE EFFECTS
* None.
*
* RETURNS
* TRUE if pSrc has implied decimal of zero, otherwise FALSE.
*
* POSSIBLE ERROR CODES
*
* GM_NULLPOINTER
*
* AUTHOR
* Andy Anderson 12-Sep-87 1435
* Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved.
*
* MODIFICATIONS
*
*
*/
#include <stdio.h>
#include "gm.h"
#include "gmsystem.h"
int IsDecimalInt(pSrc)
DEC *pSrc;
{
DEC dtemp, *temp=&dtemp;
_MacStart(GM_DISINT);
if (!pSrc) {
_MacErr(GM_NULLPOINTER);
_MacRet(GM_NULLPOINTER);
}
(void) _TruncateDec80Bit(temp, pSrc, 0);
_MacRet(CompareDecimal(temp, pSrc)==0);
}

Some files were not shown because too many files have changed in this diff Show More