From: Ton v. O. <tvo...@us...> - 2007-08-10 18:54:37
|
Update of /cvsroot/easycalc/easycalc/mlib In directory sc8-pr-cvs17:/tmp/cvs-serv6682/mlib Modified Files: fp.c Log Message: New function fp_print_g_double which behaves similar to %g format. Use it for numbers on the graph screen and on the graph preferences form instead of fp_print_double. Index: fp.c =================================================================== RCS file: /cvsroot/easycalc/easycalc/mlib/fp.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** fp.c 25 Jul 2007 01:19:41 -0000 1.14 --- fp.c 10 Aug 2007 18:54:06 -0000 1.15 *************** *** 227,254 **** } ! if( value < 0.0 ) { *strP++ = '-'; value = -value; } ! ipart = trunc(value); ! value -= ipart; /* recover frac part */ ! for (limit = 1.0,i=myfrac; i> 0;i--) { value *= BASE; limit *= BASE; } ! value += 0.5; ! if( value >= limit ) { ! fpart = 0.0; /* overflowed */ ipart++; ! } ! else ! fpart = value; ! cvt_fltoa(strP,ipart); ! ! if (myfrac || !dispPrefs.stripZeros) { cvt_fltoa(str,fpart); strP += StrLen(strP); --- 227,254 ---- } ! if( value < 0.0 ) { *strP++ = '-'; value = -value; } ! ipart = trunc(value); ! value -= ipart; /* recover frac part */ ! for (limit = 1.0,i=myfrac; i> 0;i--) { value *= BASE; limit *= BASE; } ! value += 0.5; ! if( value >= limit ) { ! fpart = 0.0; /* overflowed */ ipart++; ! } ! else ! fpart = value; ! cvt_fltoa(strP,ipart); ! ! if (myfrac || !dispPrefs.stripZeros) { cvt_fltoa(str,fpart); strP += StrLen(strP); *************** *** 271,278 **** *strP++ = flPointChar; for(i=StrLen(str); i<myfrac;i++ ) ! *strP++ = '0'; /* need some padding at the beginning */ ! StrCopy(strP,str); /* and now the value */ } ! } } --- 271,278 ---- *strP++ = flPointChar; for(i=StrLen(str); i<myfrac;i++ ) ! *strP++ = '0'; /* need some padding at the beginning */ ! StrCopy(strP,str); /* and now the value */ } ! } } *************** *** 297,301 **** } else ! StrPrintF(str,"*%d^%d",(Int16)dispPrefs.base,expon); } --- 297,301 ---- } else ! StrPrintF(str, "*%d^%d",(Int16)dispPrefs.base, expon); } *************** *** 394,395 **** --- 394,555 ---- } } + + /*********************************************************************** + * + * FUNCTION: fp_print_g_double + * + * DESCRIPTION: Formats double numbers for output on the graph screen + * using a Fortran like %g format. + * The code is derived from the printDouble function in lispme: + * http://www.lispme.de/lispme/gcc/tech.html#fpio + * + * PARAMETERS: s - output string + * value - value to be formatted + * + * RETURN: nothing + * + ***********************************************************************/ + + /* Conversion constants */ + static double pow1[] = { + 1e256, 1e128, 1e064, + 1e032, 1e016, 1e008, + 1e004, 1e002, 1e001 + }; + + static double pow2[] = { + 1e-256, 1e-128, 1e-064, + 1e-032, 1e-016, 1e-008, + 1e-004, 1e-002, 1e-001 + }; + + void fp_print_g_double(Char *s, double value, Int16 prec) PARSER; + void + fp_print_g_double(Char *s, double value, Int16 prec) + { + FlpCompDouble fcd; + double round_factor; + short e, e1, i; + double *pd, *pd1; + char sign = '\0'; + short dec = 0; + + /* Check for reasonable value of prec. IEEE double. IEEE double + * precision has about 16 significant decimal digits */ + if (prec < 0 || prec > 16) prec = 7; + + /* Initialize round_factor */ + round_factor = 0.5; + for (i = 0; i < prec; i++) round_factor /= 10.0; + + /* Check for NaN, +Inf, -Inf, 0 */ + fcd.d = value; + if ((fcd.ul[1] & 0x7ff00000) == 0x7ff00000) { + if (fcd.fdb.manH == 0 && fcd.fdb.manL == 0) { + if (fcd.fdb.sign) + StrCopy(s, "-Inf"); + else + StrCopy(s, "Inf"); + } + else { + StrCopy(s, "NaN"); + } + return; + } + if (FlpIsZero(fcd)) { + StrCopy(s, "0"); + return; + } + + /* Make positive and store sign */ + if (FlpGetSign(fcd)) { + *s++ = '-'; + FlpSetPositive(fcd); + value = fcd.d; + } + + /* Compute round_factor */ + if ((unsigned) fcd.fdb.exp < 0x3ff) { + /* round_factor for value < 1.0 */ + for (e = 1, e1 = 256, pd = pow1, pd1 = pow2; e1; + e1 >>= 1, ++pd, ++pd1) { + if (*pd1 > fcd.d) { + e += e1; + fcd.d *= *pd; + round_factor *= *pd1; + } + } + } + else { + /* round_factor for value >= 1.0 */ + for (e = 0, e1 = 256, pd = pow1, pd1 = pow2; e1; + e1 >>= 1, ++pd, ++pd1) { + if (*pd <= fcd.d) { + e += e1; + fcd.d *= *pd1; + round_factor *= *pd; + } + } + round_factor *= 10.0; + } + fcd.d = value + round_factor; + + if ((unsigned) fcd.fdb.exp < 0x3ff) { + /* Build negative exponent */ + for (e = 1, e1 = 256, pd = pow1, pd1 = pow2; e1; + e1 >>= 1, ++pd, ++pd1) { + if (*pd1 > fcd.d) { + e += e1; + fcd.d = fcd.d * *pd; + } + } + fcd.d = fcd.d * 10.0; + /* Do not print exponent for the -0.xxxx case */ + if (e <= 1) { + *s++ = '0'; + *s++ = '.'; + dec = -1; + } + else + sign = '-'; + } + else { + /* Build positive exponent */ + for (e = 0, e1 = 256, pd = pow1, pd1 = pow2; e1; + e1 >>= 1, ++pd, ++pd1) { + if (*pd <= fcd.d) { + e += e1; + fcd.d = fcd.d * *pd1; + } + } + if (e < prec) + dec = e; + else + sign = '+'; + } + + /* Extract decimal digits of mantissa */ + for (i = 0; i < prec; ++i, --dec) { + Int32 d = fcd.d; + *s++ = d + '0'; + if (!dec) + *s++ = '.'; + fcd.d = fcd.d - (double)d; + fcd.d = fcd.d * 10.0; + } + + /* Remove trailing zeros and decimal point */ + while (s[-1] == '0') + *--s = '\0'; + if (s[-1] == '.') + *--s = '\0'; + + /* Append exponent */ + if (sign) { + *s++ = 'E'; + *s++ = sign; + StrIToA(s, e); + } + else + *s = '\0'; + } |