home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
MAGAZINE
/
DDJ9309.ZIP
/
FPALIB.ZIP
/
FMTEST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-12
|
10KB
|
359 lines
/* Extended IEEE Compatible Floating Point Arithmetic Library
**
** Version 1.1
** Copyright (C) 1990, by Fred Motteler
** All Rights Reserved
**
** This is the main test routine for the extended floating point arithmetic
** package. It also tests the extended integer arithmetic package.
**
** Floating Point Format:
**
** |S| n bit signed exponent | m bit fraction |
**
** The format is compatible with IEEE Standard for Binary Floating
** when:
** n = 8, m = 23 single precision
** n = 11, m = 52 double precision
**
** If n = 15 and m = 64, this format is almost compatible with IEEE
** extended precision format. The main difference are
** 1) IEEE extended precision format is a 12 byte format with 10 bytes of
** information. Bits 64 thru 80 are zero.
** 2) The most significant bit of the mantissa (implied in single and
** double precision IEEE formats) is explicitly included.
**
** Each routine that returns a floating point result returns a condition code
** value:
**
** 0 0 0 0 N Z I n
** Where N = negative (FFNEG)
** Z = zero (FFZERO)
** I = infinite (FFINF)
** n = not a number (FFNAN)
**
** Each routine that returns a integer result returns a condition code
** value:
**
** 0 0 0 0 Z V S C
** Where Z = zero (ZERO)
** V = overflow (OVERFLOW)
** S = sign (SIGN)
** C = carry (CARRY)
**
** This is a table driven tester. It does a comprehensive test of:
** 1. Integer math operations
** 2. Integer / ASCII string conversions
** 3. Float math operations
** 4. Float / ASCII decimal conversions
** 5. Integer / Float conversions
** 6. Float / Float conversions
** 7. ASCII string / Integer conversions
** 8. ASCII string / Float conversions
**
** All numeric input and output values are specified as ASCII strings.
** This greatly simplifies setting up test cases, and provides a good test
** of the string conversion routines.
**
** Note that these routines recognize zero and infinite values. Not a number,
** or denormalized input parameters are not recogized. They blindly assume
** that the arguments are valid floating point numbers.
**
** These routines will return valid zero, infinite, and not a number values.
*/
#include <stdio.h>
#ifndef MWC
#include <stdlib.h>
#endif
#include "imlib.h"
#include "ffmlib.h"
#include "fmlib.h"
#include "fmtest.h"
#ifdef MEMTEST
/* Dynamic memory allocation test defines. */
#define FMALLSIZE 100 /* Max. number of alloc's to track. */
#define FMALLFUNC 16 /* Max. length of function id's. */
/* Memory allocation table. This is used to make sure that ALL dynamically
** allocated memory is actually freed. */
struct alloc_tab {
unsigned char *alloc_addrBP; /* Memory allocation pointer */
char func_nameAB[FMALLFUNC]; /* Name of routine allocating memory */
} fmalltabAH[FMALLSIZE]; /* Allow up to 100 memory alloc's */
/*
** Function: void fmallinit(void)
**
** This function initializes the memory allocation tracking table.
*/
void
#ifdef PROTOTYPES
fmallinit(void)
#else
fmallinit()
#endif
{
int i, j;
for (i = 0; i < FMALLSIZE; i++)
{
fmalltabAH[i].alloc_addrBP = NULL;
for (j = 0; j < FMALLFUNC; j++)
fmalltabAH[i].func_nameAB[j] = 0;
}
return;
}
/*
** Function: int fmallreport(void)
**
** This function printf's a list of memory left allocated. This function
** returns the number of memory parcels allocated.
**
** In order to keep the table from filling up, all allocated parcels
** are free'd and the table is reinitialized.
*/
int
#ifdef PROTOTYPES
fmallreport(void)
#else
fmallreport()
#endif
{
int i;
int countN; /* Allocated parcel count. */
countN = 0;
for (i = 0; i < FMALLSIZE; i++)
{
if (fmalltabAH[i].alloc_addrBP != NULL)
{
countN++;
printf("Left over allocated memory: %s address: %lx\n",
fmalltabAH[i].func_nameAB,
fmalltabAH[i].alloc_addrBP);
free(fmalltabAH[i].alloc_addrBP);
fmalltabAH[i].alloc_addrBP = NULL;
fmalltabAH[i].func_nameAB[0] = '\0';
}
}
return(countN);
}
/*
** Function: unsigned char *fmalloc(unsigned int sizeN,
** char *func_nameBP)
**
** This function allocates a block of contiguous memory with byte length given
** by sizeN. Then it enters the allocated memory's address and the
** "func_nameBP" string name into the memory allocation table.
*/
unsigned char *
#ifdef PROTOTYPES
fmalloc(unsigned int sizeN, char *func_nameBP)
#else
fmalloc(sizeN, func_nameBP)
unsigned int sizeN;
char *func_nameBP;
#endif
{
int i;
unsigned char *tempBP;
/* Allocate the desired memory, if possible. */
if ((tempBP = (unsigned char *) malloc(sizeN)) == NULL)
{
printf("Out of memory in: %s\n", func_nameBP);
return(NULL);
}
/* Search the allocation table for a free spot. When found, record this
* memory allocation. */
for (i = 0; i < FMALLSIZE; i++)
{
if (fmalltabAH[i].alloc_addrBP == NULL)
{
fmalltabAH[i].alloc_addrBP = tempBP;
strncpy(fmalltabAH[i].func_nameAB, func_nameBP, FMALLFUNC);
return(tempBP);
}
}
printf("Memory allocation table full, %s allocation not recorded.\n",
func_nameBP);
return(tempBP);
}
/*
** Function: unsigned char *fcalloc(int sizeN, int objectN,
** char *func_nameBP)
**
** This function allocates a block of zeroed contiguous memory with byte
** length given by sizeN. Then it enters the allocated memory's address
** and the "func_nameBP" string name into the memory allocation table.
*/
unsigned char *
#ifdef PROTOTYPES
fcalloc(unsigned int sizeN, unsigned int objectN, char *func_nameBP)
#else
fcalloc(sizeN, objectN, func_nameBP)
unsigned int sizeN;
unsigned int objectN;
char *func_nameBP;
#endif
{
int i;
unsigned char *tempBP;
/* Allocate the desired memory, if possible. */
if ((tempBP = (unsigned char *) calloc(sizeN, objectN)) == NULL)
{
printf("Out of memory in: %s\n", func_nameBP);
return(NULL);
}
/* Search the allocation table for a free spot. When found, record this
* memory allocation. */
for (i = 0; i < FMALLSIZE; i++)
{
if (fmalltabAH[i].alloc_addrBP == NULL)
{
fmalltabAH[i].alloc_addrBP = tempBP;
strncpy(fmalltabAH[i].func_nameAB, func_nameBP, FMALLFUNC);
return(tempBP);
}
}
printf("Memory allocation table full, %s allocation not recorded.\n",
func_nameBP);
return(tempBP);
}
/*
** Function: void ffree(unsigned char *pntrBP)
**
** This function frees the dynamically allocated memory block pointed to by
** pntrBP. It then search the memory allocation table for a matching address.
** If the address is found, then the corresponding entry in the table is
** cleared.
*/
void
#ifdef PROTOTYPES
ffree(unsigned char *pntrBP)
#else
ffree(pntrBP)
unsigned char *pntrBP;
#endif
{
int i;
free( pntrBP );
for (i = 0; i < FMALLSIZE; i++)
{
if (fmalltabAH[i].alloc_addrBP == pntrBP)
{
fmalltabAH[i].alloc_addrBP = NULL;
fmalltabAH[i].func_nameAB[0] = '\0';
return;
}
}
printf("Free address not found in allocation table: %lx\n", pntrBP);
return;
}
#endif
/*
** Function: void foutput(char *stringBP, unsigned char *floatBP,
** int lengthN)
**
** This function dumps the "object" pointed to by floatBP as a string of
** hex characters. The byte length of the object is given by lengthN.
** The string pointed to by stringBP is used to prefix the dumped value.
** The string and hex value are followed by a carriage return.
*/
void
#ifdef PROTOTYPES
foutput(char *stringBP, unsigned char *floatBP, int lengthN)
#else
foutput(stringBP, floatBP, lengthN)
char *stringBP;
unsigned char *floatBP;
int lengthN;
#endif
{
int i;
unsigned char tempB;
printf(stringBP);
for (i = 0; i < lengthN; i++)
{
tempB = *floatBP++;
if (tempB < 16)
printf("0%1x",tempB);
else
printf("%2x", tempB);
}
printf("\n");
return;
}
/*
** Function: int main()
**
** This is a table driven tester. It does a comprehensive test of:
** 1. Integer math operations
** 2. Integer / ASCII string conversions
** 3. Float math operations
** 4. Float / ASCII decimal conversions
** 5. Integer / Float conversions
** 6. Float / Float conversions
** 7. ASCII string / Integer conversions
** 8. ASCII string / Float conversions
**
** All numeric input and output values are specified as ASCII strings.
** This greatly simplifies setting up test cases, and provides a good test
** of the string conversion routines.
*/
int
#ifdef PROTOTYPES
main(void)
#else
main()
#endif
{
int testN;
int errcountN;
printf("Arbitrary Precision Floating Point Arithmetic Library Test Routine\n");
printf("Version 1.1\n");
printf("Copyright (C) 1989,1991 by Fred Motteler\n");
printf("All Rights Reserved\n\n");
testN = 0;
errcountN = 0;
/* Test basic operations for integer and float operations. */
errcountN += fmtst1(&testN);
#ifndef PARTEST
/* Test conversion operations for int to float, float to int, and
* float to float. */
errcountN += fmtst2(&testN);
/* Test conversion operation for string to int and string to float. */
errcountN += fmtst3(&testN);
#endif
printf("Total number of errors encountered: %d", errcountN);
if (errcountN == 0)
printf(" {:-)]\n");
else
printf(" {:-(]\n");
exit(errcountN);
}