home *** CD-ROM | disk | FTP | other *** search
- /*
- fndecpt.c 6/10/90
-
- % strfixdp
-
- Routines for using fixed decimal points in numeric fields.
-
- C-scape 3.2
- Copyright (c) 1990, by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 6/10/90 mla rewrote from scratch
- 7/17/90 jmd minor preening
- */
-
- #include <stdio.h>
- #include <string.h>
-
- #include <cscape.h>
-
- OSTATIC boolean is_sn(char *num, char dpc, char **dp, char **end);
- OSTATIC char *strround(char *num, char *fix);
-
- char *strfixdp(char *num, int fixdec, int len)
- /*
- * fixes fixdec decimal places in num. assumes num is a string of digits
- * with no leading spaces. maximum amount of storage for num is len.
- * if fixdec is zero, num is fixed to a whole number.
- */
- {
- char *dp, *end;
- int curdec, i;
-
- /*
- * if num is in scientific notation, do nothing.
- * else find the decimal point and end.
- */
- if (is_sn(num, ocountry.dec_char, &dp, &end)) {
- return(num);
- }
-
- if (dp == NULL) {
-
- /* num has no decimal point */
-
- /* if storage space is inadequate, clip least significant digits */
- if (len < (i = strspn(num, "0123456789")) + 1 + fixdec) {
- fixdec = len - i - 1;
- }
-
- if (fixdec == 0) {
- return(num);
- }
-
- /* add enough trailing zeroes */
- *end = ocountry.dec_char;
- for (end++; fixdec > 0; fixdec--, end++) {
- *end = '0';
- }
- *end = '\0';
-
- return(num);
- }
-
- /* else, num has a decimal point */
-
- /* if storage space is inadequate, clip least significant digits */
- if (len < (dp - num) + 1 + fixdec) {
- fixdec = len - (dp - num) - 1;
- }
-
- if (fixdec == 0) {
- *dp = '\0';
- return(num);
- }
-
- curdec = end - dp - 1;
-
- if (curdec < fixdec) {
- /* add some decimal places */
-
- for (i = (fixdec - curdec); i > 0; i--, end++) {
- *end = '0';
- }
- *end = '\0';
- }
-
- if (curdec > fixdec) {
- /* remove some decimal places */
-
- strround(num, (dp + fixdec));
- }
-
-
- /* if (curdec == fixdec), just return num */
-
- return(num);
- }
-
- static boolean is_sn(char *num, char dpc, char **dp, char **end)
- /*
- * Determines if num is in scientific notation by searching for 'E' or 'e'.
- * only if num is not in scientific notation does it report end of string
- * and location of decimal point thru extra parameters end and dp.
- */
- {
- for (; *num != '\0'; num++) {
-
- if (*num == dpc) {
- *end = num + 1;
- while (**end != '\0') {
-
- if (otoupper(**end) == 'E') {
-
- return (TRUE);
- }
- (*end)++;
- }
- *dp = num;
- return (FALSE);
- }
-
- if (otoupper(*num) == 'E') {
-
- return (TRUE);
- }
- }
-
- *end = num;
- *dp = NULL;
-
- return (FALSE);
- }
-
-
- static char *strround(char *num, char *fix)
- /*
- Rounds a string image of a floating point number off at location fix.
- The variable space for num is assumed to start at num and end at lease
- one char after fix. All checking must be done by caller.
- Num is modified in place and returned.
- */
- {
- char *s, *c;
-
- if (*(fix + 1) > '4') { /* round off? */
-
- /* work backwards thru num rounding 9's up to 0's */
- for (s = fix; s >= num && (*s == '9' || *s == '.'); s--) {
-
- if (*s == '.') {
- continue;
- }
- *s = '0';
- }
-
- /* if the high order digit of num was a 9, shift the whole
- string right one digit to make room to add a 1 */
- if (s < num) {
-
- for (c = fix; c >= s; c--) {
- *(c + 1) = *c;
- }
-
- *(s + 1) = '1';
- }
-
- /* otherwise increment the first digit that isn't a 9 */
- else {
-
- *s += 1;
- }
- }
-
- /* terminate string in either case */
- *(fix + 1) = '\0';
-
- return (num);
- }
-