[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [GNU-COBOL] math library



Matt,

Didnt you look at the orignal implementation in C using doubles??
Are you not able to replecate this functionality with the MP library?

As you can see below all you need is power, absolute value, floor, and
modulo.
YOu said you had power and module, absolute value is easy, just test
for a sign on the value(i assume the library keeps that seperate)
then do a floor...which you can go look up cause I dont have a reference
handy...or go look in the GNU C library and implement it if you have to
but its easy. Then do the below function.

any more Qs just ask.

dir: /afs/umr.edu/users/slaught/p/Cobol/Cobol2C-0.50alpha/emit
file: emit_impl.c
func: int emit_truncate_number(char *string,int length,int decimal)

Look in the big fprintf statment to see the math that is going on.

#include <stdlib.h>
#include <math.h>
#include <assert.h>

/*************************************************************************/
/*
 * Emit code to do numeric truncation
 */
/*************************************************************************/
 
int emit_truncate_number(char *string,int length,int decimal) {

	int rc;
	double pow1,pow2;

	pow1 = pow(10,length-decimal);
	pow2 = pow(10,decimal );

#if 0 
	fprintf(stderr,"EMIT::: %s, len: %d,dec: %d \n",string,length,decimal);
#endif
	rc = fprintf(gEmitEnv.source,
			"{"
			"double __tmpval,__frac,__whole;"
			"int __sign = 1;"
			" "
			"if ( %s != fabs(%s) ){"
			"__sign= -1;%s=fabs(%s);}"
			"/* split number into integral and fraction */"
/* %s - number to trunc */
			"__frac = modf( %s ,&__whole);" 
			" "
			"/* take the modulos of the integral part by	"
                        " * 10^number of digits				"
			" * to the left of the decimal 			"
			" */"
/* %d, %d - pow(10,length-decimal) */
			"__tmpval = __whole-(floor(__whole/%f)*%f);"
/* %d - pow(10,decimal ) */
			"__frac = modf( (__frac * %f ), &__whole);"
/* %d - pow(10,decimal ) */
			"__tmpval+=__whole/%f;"
			"%s=__tmpval*__sign;"
			"}"
			,string,string,string,string
			,string
			,pow1 ,pow1
			,pow2
			,pow2
			,string
	     );


	if ( rc < 0 )
		return 1;

	return 0;
}

/* 
 * Support routine :
 * function to hold temp value for a preform loop as to whether
 *  a close bracket on a loop needs to be emited. 
 *
 * ***  This function causes major re-entrent problems. *** 
 *
 *  This function is long and complicated and as soon as I figure
 *  out a better method to handle the preform statement emit code
 *  without it I will delete this monster.
 *  
 */
/*
 *  Possible Parameters - 
 *  
 *   0 - called form perform_end to close loop
 *   1 - called from perform_loop_end to 
 *        handle post-test loop
 *   2 - called from perform_iterative 
 *   3 - called from perform_before 
 *   4 - called from perform_after
 *
 */
int emit_perform_support_loop( int inFlag ){

	/* equal to zero means NOT to emit loop */
	static int emitLoopEnd = 0;
	/* handle the fucked up post test loop emission */
	static int emitAfterInfo = 0;

	int rc;

	if( inFlag == 2 || inFlag == 3) { /* called in loop */
		emitLoopEnd = 1; /* yes emit it */
		return 0;
	}
	else if ( inFlag == 4 ) {
		emitLoopEnd = 1;
		emitAfterInfo = 1;
		return 0;
	}
	else if ( inFlag == 0 ) {
		rc = emitLoopEnd;
		emitLoopEnd =0;
		return rc;
	}
	else if ( inFlag == 1) {
		rc = emitAfterInfo;
		emitAfterInfo = 0;
		return rc;
	}
	else {
		assert(0); /*fucked the monkey */
	}

	assert(0); /* NEVER get here, somethign fucked up */

}

/*
 * emit_paragraph_main_start-
 *      handle first paragraph 
 *  Placed here as to keep main parser from calling it.
 *  It is called by the emit_init function ONLY!!!!
 *  in order that variables will get declared and initalized properly
 *  Especially those in a struct.
 */
int emit_paragraph_main_start( void ) {

	int rc;
	rc=fprintf(gEmitEnv.source,
		"void main(int __argc,char** __argv){\n"
	);

	if ( rc < 0 )
		return rc;

        return 0;
}


-- 
Chad Slaughter  -- slaught at umr.edu
<PGP public key available upon request>

--
This message was sent through the gnu-cobol mailing list.  To remove yourself
from this mailing list, send a message to gnu-cobol@acm.cs.umr.edu with the
words "unsubscribe gnu-cobol" in the message body.  For more information on
the GNU COBOL project, send mail to gnu-cobol-owner@acm.cs.umr.edu.