Data Conversion

Technical Notes

Overview
Naming Conventions
Numeric-to-String Conversion-Integer
String-to-Numeric Conversion-Integer
Fixed-Point Integers
Numeric-to-String Conversion-Fixed-Point
String-to-Numeric Conversion-Fixed-Point
BCD-to-String and String-to-BCD Conversion
Converting Between Integers and BCD Numbers
Numeric-to-String Conversion-Floating-Point
String-to-Numeric Conversion-Floating-Point
Initializing the Data Conversion Formatting Functions
Formatting and Unformatting Numeric Strings
Sample Program

Overview

This unit consists of functions which perform numeric-to-string and string-to-numeric data conversion on integer, floating-point, fixed-point integer, and BCD numeric types. Functions are also included which format ASCII numeric strings, convert formatted ASCII numeric strings to standard format ASCII numeric strings, and convert BCD numbers to and from integers.

The integer conversion functions read or write ASCII strings representing numbers in base 10 (decimal), base 16 (hexadecimal), or in a specified base from 2 to 36. The floating-point, fixed-point, BCD conversion, and formatting functions read or write ASCII strings in base 10 (decimal). Supported integer numeric types include char, int, long, and quad in both signed and unsigned representations. Supported fixed-point numeric types include int, long, and quad in both signed and unsigned representations. Supported floating-point types include float (32 bit), double (64 bit), and long double (80 bit) reals. The supported bcd numeric type is a packed ten byte (80 bit) signed BCD format.

The numeric-to-string and string-to-numeric formatting functions in this unit support the following formatting options:

Formatting Option                                        Examples

Currency symbol string (arbitrary or country-specific)      "$1.23", "Cr$1,23", ...
Currency symbol position (arbitrary or country-specific)    "1.23 ", "1,23", ...
Thousands delimiter (arbitrary or country-specific)         "1,234.56", "1.234,56", ...
Decimal delimiter (arbitrary or country-specific)           "1.23", "1,23", ...
Precision (arbitrary or country-specific)               "1.23", "1.23456" (0 to 30 digits)
Maximum field width                                     (0 to 126 characters)
Positive number representation                      "123", "CR 123", "+123", "123+", ...
Negative number representation                      "-123", "(123)", "< 123 >", "123-", ...
Truncated or rounded result                         1.226 to "1.22" or "1.23"
Fixed, floating, padded digits to right of decimal point    1.200 to "1.2", "1.200", or "1.2  "
Use a leading zero for numbers between -1 and 1             "0.123" or ".123"
Exponent indicator string                                   "1.2E34", "1.2x10^34", ...
Minimum number of digits in the exponent            "1.2e3", "1.2e03", "1.2e003", "1.2e0003"
Optional "+" for positive exponents                 "1.2e+34" or "1.2e34"
Output format:       integer, exponential, non-exponential, or flex-exponential

Naming Conventions

Numeric-to-string conversion functions follow a naming convention of numeric_TO_string, where numeric is a descriptive name for the numeric type and string is a descriptive name for the string type. String-to-numeric conversion functions follow a naming convention of string_TO_numeric.

The descriptive names used for numeric and string types are as follows:

Descriptive Name  Description                       Range or Radix

uc                unsigned char                                0 to 255
c                 char                                      -128 to 127
ui                unsigned int                                 0 to 65,535
i                 int                                    -32,768 to 32,767
ul                unsigned long                                0 to 4,294,967,295
l                 long                                      -231 to 231-1
uq                uquad                                        0 to 264-1
q                 quad                                      -263 to 263-1
ufixpi            fixed-point unsigned int                  0.00 to 655.35*
fixpi             fixed-point int                        -327.68 to 327.67*
ufixpl            fixed-point unsigned long                 0.00 to 42,949,672.95*
fixpl             fixed-point long                -21,474,836.48 to 21,474,836.47*
ufixpq            fixed-point uquad                         0.00 to 184,467,440,737,095,516.15*
fixpq             fixed-point quad    -92,233,720,368,547,758.08 to 92,233,720,368,547,758.07*
bcd               binary coded decimal (packed)          -1018+1 to 1018-1
f                 float (32-bit real)                1.17x10-38 to 3.40x1038
d                 double (64-bit real)              2.22x10-308 to 1.79x10308
ld                long double (80-bit real)        3.36x10-4932 to 1.19x104932

asc               ASCII string of alphanumeric digits2  radix  36
dec               ASCII string of decimal digitsradix = 10
hex               ASCII string of hexadecimal digitsradix = 16
*The position of the decimal point in a fixed-point number must be specified. This representation assumes a fixed-point precision of two.

Because C does not supply defined types for 64-bit integers or BCD values, the following typedefs are provided to simplify the use of 64-bit integer and BCD types in C applications: uquad for unsigned 64-bit integers, quad for signed 64-bit integers and bcd for binary coded decimal values. The bcd, quad and uquad types are defined using typedef, as follows:


typedef signed char quad[8];
typedef unsigned char uquad[8];
typedef unsigned char bcd[10];

Numeric-to-String Conversion-Integer

_uc_to_hex
Converts an unsigned char to a hexadecimal ASCIIZ string.
_uc_to_hexe
Converts an unsigned char to a hexadecimal ASCII string, returning a pointer to the end of the resulting string.
_ui_to_hex
Converts an unsigned int to a hexadecimal ASCIIZ string.
_ui_to_hexe
Converts an unsigned int to a hexadecimal ASCII string, returning a pointer to the end of the resulting string.
_uc_to_dec
Converts an unsigned char to a decimal ASCIIZ string.
_uc_to_dece
Converts an unsigned char to a decimal ASCII string, returning a pointer to the end of the resulting string.
_c_to_dec
Converts a char to a decimal ASCIIZ string.
_c_to_dece
Converts a char to a decimal ASCII string, returning a pointer to the end of the resulting string.
_ui_to_dec
Converts an unsigned int to a decimal ASCIIZ string.
_ui_to_dece
Converts an unsigned int to a decimal ASCII string, returning a pointer to the end of the resulting string.
_i_to_dec
Converts a int to a decimal ASCIIZ string.
_i_to_dece
Converts a int to a decimal ASCII string, returning a pointer to the end of the resulting string.
_ul_to_dec
Converts an unsigned long to a decimal ASCIIZ string.
_ul_to_dece
Converts an unsigned long to a decimal ASCII string, returning a pointer to the end of the resulting string.
_l_to_dec
Converts a long to a decimal ASCIIZ string.
_l_to_dece
Converts a long to a decimal ASCII string, returning a pointer to the end of the resulting string.
_uq_to_dec
Converts a uquad to a decimal ASCIIZ string.
_uq_to_dece
Converts a uquad to a decimal ASCII string, returning a pointer to the end of the resulting string.
_q_to_dec
Converts a quad to a decimal ASCIIZ string.
_q_to_dece
Converts a quad to a decimal ASCII string, returning a pointer to the end of the resulting string.
_uc_to_asc
Converts an unsigned char to an ASCIIZ string in a given radix.
_uc_to_asce
Converts an unsigned char to an ASCII string in a given radix, returning a pointer to the end of the resulting string.
_c_to_asc
Converts a char to an ASCIIZ string in a given radix.
_c_to_asce
Converts a char to an ASCII string in a given radix, returning a pointer to the end of the resulting string.
_ui_to_asc
Converts an unsigned int to an ASCIIZ string in a given radix.
_ui_to_asce
Converts an unsigned int to an ASCII string in a given radix, returning a pointer to the end of the resulting string.
_i_to_asc
Converts a int to an ASCIIZ string in a given radix.
_i_to_asce
Converts a int to an ASCII string in a given radix, returning a pointer to the end of the resulting string.
_ul_to_asc
Converts an unsigned long to an ASCIIZ string in a given radix.
_ul_to_asce
Converts an unsigned long to an ASCII string in a given radix, returning a pointer to the end of the resulting string.
_l_to_asc
Converts a long to an ASCIIZ string in a given radix.
_l_to_asce
Converts a long to an ASCII string in a given radix, returning a pointer to the end of the resulting string.
_uq_to_asc
Converts a uquad to an ASCIIZ string in a given radix.
_uq_to_asce
Converts a uquad to an ASCII string in a given radix, returning a pointer to the end of the resulting string.
_q_to_asc
Converts a quad to an ASCIIZ string in a given radix.
_q_to_asce
Converts a quad to an ASCII string in a given radix, returning a pointer to the end of the resulting string.
These functions convert a numeric value to a string of alphanumeric ASCII digits. The ..._to_asc and ..._to_asce functions accept a radix as an input and convert the numeric value to a string of alphanumeric ASCII digits in the given radix. The ..._to_hex, ..._to_hexe, ..._to_dec and ..._to_dece functions convert the numeric value directly to a hexadecimal or decimal ASCII string. All numeric-to-string functions output uppercase ASCII letters for digits above decimal nine. For example, in base 11 and above, 1010 is represented as "A" rather than "a".

The ..._to_dec functions produce output strings in decimal ASCII integer format, which is a special case of the standard non-exponential format. Strings in this format may be used with the formatting functions described later in this chapter. Decimal ASCII integer format is defined as follows:

[-][d...]d
(where d denotes any decimal digit)
Function names which end with an "e" denote functions which return a pointer to the character after the end of the resulting string. These functions do NOT terminate the resulting string with a NULL. Functions which accept signed input values always place a minus sign at the beginning of the resulting string if the input value is negative.

The following example takes advantage of the fact that _ui_to_dece returns a pointer to the end of the resulting string:


#include                 
#include                 
#include                 

char xy_msg[] = "X,Y coordinates: (";
char xy_coord[11];
char *ptr;

void main(void)
{
   ptr = _i_to_dece(23,xy_coord);
   *ptr++ = ',';
   ptr = _i_to_dece(45,ptr+1);
   *ptr++ = ')';
   *ptr = 0;
   _put_str(_str_cat(xy_msg, xy_coord));
}
In the example above, the displayed string would be "X,Y coordinates: (23,45)".

String-to-Numeric Conversion-Integer

_asc_to_uc
Converts an ASCII string to an unsigned char in a given radix.
_asc_to_c
Converts an ASCII string to a char in a given radix.
_asc_to_ui
Converts an ASCII string to an unsigned int in a given radix.
_asc_to_i
Converts an ASCII string to a int in a given radix.
_asc_to_ul
Converts an ASCII string to an unsigned long in a given radix.
_asc_to_l
Converts an ASCII string to a long in a given radix.
_asc_to_uq
Converts an ASCII string to a uquad in a given radix.
_asc_to_q
Converts an ASCII string to a quad in a given radix.
_dec_to_uc
Converts a decimal ASCII string to an unsigned char.
_dec_to_c
Converts a decimal ASCII string to a char.
_dec_to_ui
Converts a decimal ASCII string to an unsigned int.
_dec_to_i
Converts a decimal ASCII string to a int.
_dec_to_ul
Converts a decimal ASCII string to an unsigned long.
_dec_to_l
Converts a decimal ASCII string to a long.
_dec_to_uq
Converts a decimal ASCII string to a uquad.
_dec_to_q
Converts a decimal ASCII string to a quad.
_hex_to_uc
Converts a hexadecimal ASCII string to an unsigned char.
_hex_to_ui
Converts a hexadecimal ASCII string to an unsigned int.
These functions convert digits from an ASCII string to a binary value. The _hex_to_... and _dec_to_... functions interpret the characters from the string as hexadecimal or decimal digits, respectively. The _asc_to_... functions interpret the characters as digits in a specified radix from 2 to 36. The unsigned functions treat leading plus or minus signs as invalid characters; the signed functions accept a single leading plus or minus sign.

Both upper and lowercase ASCII letters are recognized as digits in the range 1010 to 3510 . For example, in base 11 and above, either "A" or "a" is equivalent to 1010 , and in base 36, both "Z" and "z" are accepted as 3510 .

All of the string-to-numeric conversion functions return a pointer to the first string character which is not a valid digit. Leading white space characters are not automatically skipped since this is not always desirable. If white space characters should be skipped, call _str_skipw or _str_skips before calling the string-to-numeric function.

The integer string-to-numeric conversion functions are subject to overflow. The char and int functions provide simple overflow checking. In the event of overflow, 1 is returned in the global c_code condition variable, an index pointer is advanced past the entire number, and the return value is undefined. This provides some overflow checking without hindering execution speed; it also allows overflow to be ignored without writing additional code. The long and quad functions do notcheck for overflow because it cannot be done without seriously hindering execution speed. If overflow occurs, the return value is undefined. Note that the _hex_to_... functions do not provide an overflow return. Instead, they provide a return which indicates that more hexadecimal digits remain to be processed.

Fixed-Point Integers

Fixed-point integers are true integer values with an implied number of decimal digits to the right of an implied decimal point. The precision of a fixed-point number specifies the fixed number of digits to the right of the decimal point. (Restated, fixed-point integers have implied exponents of precision or a value of fixed-point10precision.)

For example, a fixed-point integer value of 54,321 with a precision of 3 represents 54321e-3 or 54.321. A fixed-point integer value of 10,025 in U.S. monetary units (precision of 2), represents 10,025 cents or $100.25.

The precision of a fixed-point value is only specified when the _dec_to_fixp or _fixp_to_dec data conversion functions are called. In all other respects, fixed-point integers are treated as integer values. Because fixed-point integers are manipulated using standard integer math routines, they provide a fast, tight alternative to floating-point values.

WARNING! It is the responsibility of the programmer to keep track of the precision of each fixed-point value. When fixed-point values are multiplied, their precisions must be added to determine the precision of the result. When fixed-point values are divided, the precision of the divisor must be subtracted from the precision of the dividend. Negative precisions are not supported. Standard integer values have a precision of 0.

Numeric-to-String Conversion-Fixed-Point

_ufixpi_to_dec
Converts a fixed-point unsigned int to a decimal ASCIIZ string.
_fixpi_to_dec
Converts a fixed-point int to a decimal ASCIIZ string.
_ufixpi_to_dece
Converts a fixed-point unsigned int to a decimal ASCII string, returning a pointer to the end of the resulting string.
_fixpi_to_dece
Converts a fixed-point int to a decimal ASCII string, returning a pointer to the end of the resulting string.
_ufixpl_to_dec
Converts a fixed-point unsigned long to a decimal ASCIIZ string.
_fixpl_to_dec
Converts a fixed-point long to a decimal ASCIIZ string.
_ufixpl_to_dece
Converts a fixed-point unsigned long to a decimal ASCII string, returning a pointer to the end of the resulting string.
_fixpl_to_dece
Converts a fixed-point long to a decimal ASCII string, returning a pointer to the end of the resulting string.
_ufixpq_to_dec
Converts a fixed-point uquad to a decimal ASCIIZ string.
_fixpq_to_dec
Converts a fixed-point quad to a decimal ASCIIZ string.
_ufixpq_to_dece
Converts a fixed-point uquad to a decimal ascii string, returning a pointer to the end of the resulting string.
_fixpq_to_dece
Converts a fixed-point quad to a decimal ASCII string, returning a pointer to the end of the resulting string.
The fixp_to_dec functions convert fixed-point numeric values to strings of ASCII digits. These functions allow fixed-point numeric values to be maintained as integers and output with an embedded decimal point. (See Fixed-Point Integers, above, for a discussion of fixed-point integers.)

Functions which write out an ASCIIZ string return a pointer to the beginning of the resulting string. Function with names which end with an "e" write out non-NULL terminated ASCII strings and return a pointer to the first character past the end of the string. This makes it possible to append additional characters very rapidly. Functions which accept signed input values always place a minus sign at the beginning of the resulting string if the input value is negative.

The fixp_to_dec functions create output strings in decimal ASCII fixed-point format, which is a special case of standard non-exponential format. Strings in this format may be used with theformatting functions described later in this chapter. Decimal ASCII fixed-point format is defined as follows:

[-][d...][.][d...]
(where d denotes any decimal digit)

String-to-Numeric Conversion-Fixed-Point

_dec_to_ufixpi
Converts a decimal ASCII string to a fixed-point unsigned int.
_dec_to_fixpi
Converts a decimal ASCII string to a fixed-point int.
_dec_to_ufixpl
Converts a decimal ASCII string to a fixed-point unsigned long.
_dec_to_fixpl
Converts a decimal ASCII string to a fixed-point long.
_dec_to_ufixpq
Converts a decimal ASCII string to a fixed-point uquad.
_dec_to_fixpq
Converts a decimal ASCII string to a fixed-point quad.
These functions convert decimal ASCII strings to fixed-point integer values. The unsigned functions treat leading plus or minus signs as invalid characters; the signed functions accept a single leading plus or minus sign. All functions recognize a decimal character (".") as a valid character. (See Fixed-Point Integers, above, for a discussion of fixed-point integers.)

All of the fixed-point-to-numeric functions return a pointer to the first string character which is not a valid digit. Leading white space characters are not automatically skipped since this is not always desirable. To skip leading white space characters, call _str_skipw or _str_skips before calling the fixed-point-to-numeric function.

The integer fixed-point-to-numeric conversion functions are subject to overflow. The int functions provide simple overflow checking. In the event of overflow, 1 is returned in the global c_code condition variable, an index pointer is advanced past the entire number, and the return value is undefined. This provides some overflow checking without hindering execution speed; it also allows overflow to be ignored without writing additional code. The long and quad functions do not check for overflow because checking cannot be done without seriously hindering execution speed. If overflow occurs, the return value is undefined.

BCD-to-String and String-to-BCD Conversion

_bcd_to_dec
Converts a bcd number to a decimal ASCIIZ string.
_bcd_to_dece
Converts a bcd number to a decimal ASCII string, returning a pointer to the end of the resulting string.
_dec_to_bcd
Converts an ASCII string to a bcd number.
The _bcd_to_dec... functions convert numeric bcd values to strings of decimal ASCII digits. These functions support the same packed bcd format which is supported by the 8087 numeric coprocessor. However, these functions do NOT require a numeric coprocessor.

The _bcd_to_dec... functions accept signed input values and always place a minus sign at the beginning of the resulting string if the input value is negative. _bcd_to_dec writes out an ASCIIZ string and returns a pointer to the beginning of the resulting string. _bcd_to_dece writes out a non-NULL terminated ASCII string and returns a pointer to the first character past the end of the string. This makes it possible to append additional characters more rapidly than is possible with _bcd_to_dec.

_dec_to_bcd converts digits from an ASCII string to a bcd value. This function accepts an optional leading plus or minus sign followed by the ASCII digits to convert. The returned pointer points to the first string character which is not a valid digit. _dec_to_bcd does not check for overflow. Leading white space characters are not automatically skipped since this is not always desirable. To skip leading white space characters, call _str_skipw or _str_skips before calling the string-to-numeric function.

The _bcd_to_dec functions create output strings in decimal ASCII integer format, which is a special case of standard non-exponential format. Strings in this format may be used with the numeric formatting functions described later in this chapter. Decimal ASCII integer format is defined as follows:

[-][d...]d
(where d denotes any decimal digit)

Converting Between Integers and BCD Numbers

_q_to_bcd
Converts a quad to a BCD number.
_bcd_to_q
Converts a BCD number to a quad.
These functions provide conversion facilities between quad integers and packed bcd numbers. The format of the packed bcd number is the same format supported by the 8087 numeric coprocessor. These functions do NOT require a numeric coprocessor and are provided to allow integer math facilities to be used for bcd numbers.

Numeric-to-String Conversion-Floating-Point

_f_to_dec
Converts a float to a decimal ASCIIZ string in standard exponential format.
_f_to_dece
Converts a float to a decimal ASCII string in standard exponential format, returning a pointer to the end of the resulting string.
_f_to_decn
Converts a float to a decimal ASCIIZ string in standard non-exponential format.
_f_to_decne
Converts a float to a decimal ASCII string in standard non-exponential format, returning a pointer to the end of the resulting string.
_d_to_dec
Converts a double to a decimal ASCIIZ string in standard exponential format.
_d_to_dece
Converts a double to a decimal ASCII string in standard exponential format, returning a pointer to the end of the resulting string.
_d_to_decn
Converts a double to a decimal ASCIIZ string in standard non-exponential format.
_d_to_decne
Converts a double to a decimal ASCII string in standard non-exponential format, returning a pointer to the end of the resulting string.
_ld_to_dec
Converts a long double to a decimal ASCIIZ string in standard exponential format.
_ld_to_dece
Converts a long double to a decimal ASCII string in standard exponential format, returning a pointer to the end of the resulting string.
_ld_to_decn
Converts a long double to a decimal ASCIIZ string in standard non-exponential format.
_ld_to_decne
Converts a long double to a decimal ASCII string in standard non-exponential format, returning a pointer to the end of the resulting string.
These functions convert a floating-point numeric value to a decimal ASCII string in standard exponential or non-exponential format. A numeric coprocessor or 8087 compatible emulator is required for these functions. When these functions are used, the appropriate floating-point conversion library (_FPC??.LIB) must also be linked in.

The ..._to_dec and ..._to_dece functions convert the floating-point value directly to an ASCII string in standard exponential format. The ..._to_decn and ..._to_decne functions convert the floating-point value directly to an ASCII string in standard non-exponential format. These standard formats are defined as follows:

Standard Exponential Format:

[-]d[.][d...]e[-]d[d...](where d denotes any decimal digit)

Standard Non-Exponential Format:

[-][d...]d[.][d...] (where d denotes any decimal digit)

Functions which write out an ASCIIZ string return a pointer to the beginning of the resulting string. Functions with names which end with an "e" write out non-NULL terminated ASCII strings andreturn a pointer to the end of the resulting string. This makes it possible to append additional characters very rapidly.

A minus sign is always written at the beginning of the resulting string if the input value is negative. No decimal point is written if there are no digits after the decimal point (e.g., "12345" and "1e2"). Floating-point numbers in the range -1 < n < 1 which are converted to non-exponential format are written with a leading zero (e.g., 1.234e-2 is converted to "0.01234" in non-exponential format).

String-to-Numeric Conversion-Floating-Point

_dec_to_f
Converts an ASCII string to a float.
_dec_to_d
Converts an ASCII string to a double.
_dec_to_ld
Converts an ASCII string to a long double.
These functions convert digits from a standard exponential or non-exponential format ASCII string to a floating-point value. A numeric coprocessor or 8087 compatible emulator is required for these functions. When these functions are used, the appropriate floating-point conversion library (_FPC??.LIB) must also be linked in.

These functions accept an optional leading plus or minus sign followed by the ASCII digits to convert. The following characters are also allowed in the string: a leading minus sign ("-"), a decimal point ("."), the default exponent indicator ("e"), and a minus sign in the exponent (as in "-1.23e-4"). A pointer is returned to the first string character which is not a valid character. Leading white space characters are not automatically skipped. To skip leading white space characters, call _str_skipw or _str_skips before calling these string-to-numeric functions.

The numeric result of these functions uses IEEE floating-point format (interpretable by the 8087 numeric coprocessor).

Initializing the Data Conversion Formatting Functions

dc_addr
(Variable) Contains the address of the current data conversion options structure.
_dc_init
Initializes the current data conversion options structure with DOS country information.
dc_addr is a near/far pointer that contains the address of the current data conversion options structure (dcopts). In small data models (TINY, SMALL, MEDIUM), this variable is a near pointer which contains the offset of the structure within DGROUP (global or static non-far data). In large data models (COMPACT, LARGE, HUGE), this variable is a far pointer which contains the segment and offset of the structure. The current dcopts structure specifies global data conversion formatting options and is used by _form_to_dec, _dec_to_form, and the scripted I/O functions. The behavior of these functions may be changed by modifying this structure or by modifying dc_addr to point to a different dcopts structure.

dc_addr is initialized with the address of the default dcopts structure. The default dcopts structure is defined in DATACONV.H as follows:


typedef struct {
   char * dc_leadplus;            /* leading plus string pointer ("+") */
   char * dc_trailplus;                   /* trailing plus string pointer (NULL) */
   char * dc_leadneg;                     /* leading neg string pointer ("-") */
   char * dc_trailneg;                    /* trailing neg string pointer (NULL) */
   char * dc_expstr;                      /* exponent string pointer ("e") */
   char dc_curstr[6];                     /* ASCIIZ currency string ("$") */
   char dc_thdelim;                       /* thousands delimiter (",") */
   char dc_decdelim;                      /* decimal delimiter (".") */
   char dc_curdigits;                     /* currency digits after decimal point (2) */
   unsigned char dc_flags;        /* currency location, use "+" in exp, suppress
                                                     leading zero, min number of exponent digits */
} dcopts;
The DC_DEFAULT symbolic constant (defined in DATACONV.H) may be specified for any field which accepts a pointer. This causes the data conversion functions to use the default string, shown in the comments above, for each field in which it is specified.

Each field in the dcopts structure specifies a data conversion option. The dcopts structure fields are defined as follows:

dc_leadplus
Address of the leading positive sign indicator string. If DC_DEFAULT is specified, the default "+" string is assumed. If a string address is specified, that string is used in place of the default "+" string. This string precedes positive decimal strings if the DC_PLUS formatting flag is specified (see _dec_to_form).
dc_trailplus
Address of the trailing positive sign indicator string. If DC_DEFAULT is specified, a NULL string is assumed. If a string address is specified, that string is used instead. This string follows positive ASCII decimal strings if the DC_PLUS formatting flag is specified (see _dec_to_form).
dc_leadneg
Address of the leading minus sign indicator string. If DC_DEFAULT is specified, the default "-" string is assumed. If a string address is specified, that string is used in place of the default "-" string. This string precedes negative ASCII decimal strings.
dc_trailneg
Address of the trailing negative sign indicator string. If DC_DEFAULT is specified, a NULL string is assumed. If a string address is specified, that string is used instead. This string follows negative ASCII decimal strings.
dc_expstr
Address of the exponent indicator string. If DC_DEFAULT is specified, the default "e" exponent indicator is assumed. If a string address is specified, it is used in place of the default "e" exponent indicator.
dc_curstr
Currency symbol string (ASCIIZ). If a currency format is selected, this immediate string either precedes or follows the decimal ASCII string depending on the state of the DC_CPRECEDE bit in the dc_flags field. The default string is "$". This field is updated by _dc_init. (This field is defined as a string instead of a string pointer for compatibility with DOS country information.)
dc_thdelim
Thousands delimiter character. This character appears after every third significant digit from right to left, starting at the decimal point in the decimal ASCII string. The default character is the comma. This character only appears if the DC_THOUS formatting flag is specified (see _dec_to_form). This field is updated by _dc_init.
dc_decdelim
Decimal delimiter character. This character separates the integer and fractional portions of the decimal ASCII string. The default character is a period. This field is updated by _dc_init.
dc_curdigits
Number of digits to the right of the decimal point in country-specific currency strings. The default is 2 digits. This field is updated by _dc_init.
dc_flags
Miscellaneous formatting information (see the dc_flag equates below). All bits are clear by default. Portions of this field are updated by _dc_init.
The following symbolic constants (defined in DATACONV.H) may be used to check or modify the information in the dc_flags field:
DC_CPRECEDE
(0x00) Currency symbol precedes the number (default)
DC_CFOLLOW
(0x01) Currency symbol follows the number
DC_NOEXPPLUS
(0x00) No "+" on positive exponent strings (default)
DC_EXPPLUS
(0x04) Use "+" on positive exponent strings
DC_LEADZERO
(0x00) Use leading zero if number would start with "." (default)
DC_NOLEADZERO
(0x08) No leading zero if number would start with "."
DC_MINEXP1
(0x00) Use minimum of 1 digit in exponent (default)
DC_MINEXP2
(0x40) Use minimum of 2 digits in exponent
DC_MINEXP3
(0x80) Use minimum of 3 digits in exponent
DC_MINEXP4
(0xC0) Use minimum of 4 digits in exponent
Defines with a value of zero are the defaults and are provided for completeness only.
_dc_init
updates the current data conversion options structure (referenced by dc_addr) with the DOS country information for the current or specified country. Updated information includes the currency string, thousands delimiter, decimal delimiter, currency digits, and currency symbol position. (The currency position is stored by setting DC_CURR_PN or DC_CURR_FN in dc_flags and prefixing or appending the appropriate number of space characters to the currency symbol string specified in dc_curstr.) This function does not need to be called if the dcopts structure already contains the correct information.

Formatting and Unformatting Numeric Strings

_dec_to_form
Converts a decimal ASCII numeric string to a formatted decimal ASCIIZ numeric string.
_dec_to_forme
Converts a decimal ASCII numeric string to a formatted decimal ASCII numeric string, returning a pointer to the end of the resulting string.
_fdec_to_form
Converts a standard decimal ASCII string to a formatted decimal ASCIIZ string using far pointers.
_fdec_to_forme
Converts a standard decimal ASCII string to a formatted decimal ASCII string using far pointers, returning a pointer to the end of the resulting string.
_form_to_dec
Converts a formatted decimal ASCII string to a standard decimal ASCIIZ string.
_form_to_dece
Converts a formatted decimal ASCII string to a standard decimal ASCII string, returning a pointer to the end of the resulting string.
_fform_to_dec
Converts a formatted decimal ASCII string to a standard decimal ASCIIZ string using far pointers.
_fform_to_dece
Converts a formatted decimal ASCII string to a standard decimal ASCII string using far pointers, returning a pointer to the end of the resulting string.
The _dec_to_form... and _fdec_to_form... functions convert decimal ASCII strings to formatted decimal ASCII strings. Strings are formatted by fixing the precision to the right of the decimal point (if applicable), inserting thousands separators, currency symbols, etc. Input strings must be in standard exponential or standard non-exponential format with an optional leading plus sign character for positive values.

The _form_to_dec... and _fform_to_dec... functions strip formatting characters from formatted decimal ASCII strings to create exponential or non-exponential decimal ASCII strings.

_dec_to_form, _fdec_to_form, _form_to_dec, and _fform_to_dec return a pointer to the resulting ASCIIZ string. _dec_to_forme, _fdec_to_forme, _fform_to_dece, and _form_to_dece return a pointer to the end of the resulting non-NULL terminated string. This makes it possible to append additional characters very rapidly. Leading white space characters are not automatically skipped. To skip leading white space characters, call _str_skipw or _str_skips before calling these formatting functions.

A numeric coprocessor is NOT required for these formatting functions.

When formatting is performed, the precision of the result is specified and the result is never allowed to exceed a specified number of characters (width). The format of the result is specified in three places: 1) the current data conversion options structure; 2) numeric formatting flags which specify plus sign, currency, thousands, and exponential format options, and 3) precision flags which specify rounding, truncation, and significant digit formatting options. For the _dec_to_form functions, these options designate the final appearance of the formatted output string. For the _form_to_dec functions, these options indicate the expected format of the formatted input string.

The current data conversion options structure specifies global formatting options such as sign indicator strings, thousands delimiter, decimal delimiter, currency symbol location, currency precision, exponent string, exponent sign suppression, minimum number of exponent digits, and zero suppression before the decimal point. These options may be accessed or modified through the dc_addr variable. (See dc_addr, above, for further information.)

Numeric formatting options are specified using the following symbolic constants (defined in DATACONV.H):

DC_NOPLUS
(0x00) No plus sign is written if the value is positive. On input, no plus sign is allowed.
DC_PLUS
(0x10) A plus sign is written if the value is positive. On input, a plus sign is allowed and is specifically checked for. The plus sign is read or written using the leading/trailing plus sign strings which are specified in the current dcopts structure.
DC_NOCURRENCY
(0x00) No currency symbol is inserted into the result. On input, no currency symbols are allowed.
DC_CURRENCY
(0x08) A currency symbol is inserted into the result in the position specified in the current dcopts structure. On input, currency symbols are checked for and removed if present. The currency symbol and insertion position are specified in the current dcopts structure.
DC_NOTHOUS
(0x00) Thousands separators are not used in the result. On input, thousands separators are not allowed.
DC_THOUS
(0x04) Thousands separators are used in the result. On input, thousands separators are allowed. Separators appear only to the left of the decimal point.
DC_NOEXP
(0x00) The result is written in non-exponential form; NULL is returned if the result exceeds width. On input, exponential format is specifically disallowed; if an exponential number is read, then only the mantissa is converted (the exponent is ignored).
DC_EXP
(0x01) The result is written in exponential form; NULL is returned if the result exceeds width. On input, exponential format is allowed.
DC_FLEX
(0x02) The result is written in non-exponential form if possible; precision indicates the maximum or required number of digits to the right of the decimal point. On input, exponential format is allowed. This format supports all possible output values in a more consistent and visually pleasing form than the "G" or "g" formats supported by printf. The result is written in exponential form if the non-exponential result would exceed width. If exponential form must be used, the maximum possible number of digits are written to the right of the decimal point; NULL is returned if the exponential result would exceed width.
Precision flags are specified by bitwise ORing together the constants from the following list (defined in DATACONV.H) into the specified precision value:
DC_ROUND
(0x00) The result is rounded if required. "Round to nearest" is the rounding method employed. If both destinations are equidistant, then "rounding away from zero" is performed.
DC_TRUNC
(0x20) The result is not rounded. Less significant digits are truncated.
DC_FIX
(0x00) Forces precision digits to the right of the decimal point by appending trailing zeros if necessary. This option is ignored on input.
DC_FILL
(0x40) Forces precision characters to the right of the decimal point by replacing trailing zeros with the space character. If the decimal point is suppressed, it is also replaced with the space character. (Note that this inserts space characters between the mantissa and exponent in exponential format.) This option causes trailing space characters to be skipped after the mantissa on input.
DC_FLOAT
(0x80) Allows at most precision digits to right of the decimal point. Trailing zeros are not written. The decimal point is suppressed if there are no digits to the right of the decimal point. This option is ignored on input.
In addition, the following constant allows the precision of currency strings to be specified in a country-independent manner whether or not a currency symbol is written. This constant is used in place of the precision value specified in the precision parameter:
DC_CDIGITS
(0x1F) Use the country-specific precision specified for currency in the dc_curdigits field of the current data conversion options structure.
width must be in the range 0 to 126. A width of 0 denotes "no limit" (which translates into the maximum internally supported width of at least 126 characters).

The following table of flags, input strings, and output strings shows the results of some simple combinations of numeric and precision flags. These examples all assume a precision of 2:

Input strings:  "155.0023"  "3.1209e1"   "12045"   "3.006e12"
Numeric flags:  DC_NOEXP    DC_NOEXP     DC_EXP    DC_EXP

Precision flags output strings:
DC_ROUND+DC_FIX    "155.00"    "31.21"    "1.20e4"     "3.01e12"
DC_ROUND+DC_FILL   "155   "    "31.21"    "1.2 e4"     "3.01e12"
DC_ROUND+DC_FLOAT  "155"       "31.21"    "1.2e4"      "3.01e12"
DC_TRUNC+DC_FIX    "155.00"    "31.20"    "1.20e4"     "3.00e12"
DC_TRUNC+DC_FILL   "155   "    "31.2 "    "1.2 e4"     "3   e12"
DC_TRUNC+DC_FLOAT  "155"       "31.2"     "1.2e4"      "3e12"
Requirements for Using Floating-Point Conversion Functions

Most of the ASCII-to-floating-point and floating-point-to-ASCII conversion functions make use of the 80x87 floating-point instruction set. Therefore, the appliction must be linked with floating-point emulation enabled if these functions are used in an application which may be run on a system without a coprocessor. This requirement is documented in the reference section for each function to which it applies.

Spontaneous Assembly functions which use 8087 floating-point instructions are NOT present in the standard libraries (_SA?.LIB). Instead, these functions are found in separate floating-point libraries (_FPC??.LIB) which have been pre-assembled to support specific compilers or a numeric coprocessor (no floating-point emulation). These libraries are as follows:

Library Description

FPCBm.LIB
Spontaneous Assembly functions which have been assembled specifically for use with Borland/Turbo C/C++
FPCMm.LIB
Spontaneous Assembly functions which have been assembled specifically for use with Microsoft C/C++
FPCTm.LIB
Spontaneous Assembly functions which have been assembled specifically for use with TopSpeed C
FPCZm.LIB
Spontaneous Assembly functions which have been assembled specifically for use with Zortech C++
FPCNm.LIB
Spontaneous Assembly functions which have been assembled for use in systems which have a numeric coprocessor
In each library name shown above, m denotes a single letter (T, S, M, C, or L) which indicates one of the five standard memory models (TINY, SMALL, MEDIUM, COMPACT, or LARGE).

FPCNm.LIB should be used if floating-point facilities are not required by the application.

At present, only the floating-point data conversion functions (_DF*.ASM) are included in these special floating-point coprocessor libraries.

Sample Program

The CALC sample program described in the Integer Math technical notes uses several data conversion functions and demonstrates conversions from asc-to-quad and quad-to-asc in various radices.