![]() |
![]() |
![]() |
![]() |
10 Conversions (conv.hhf)
This HLA unit contains routines that perform general conversions from one data type to another. Primarily, this unit supplies the routines that convert HLA data types to and from string form.
10.1 Conversion Format Control
conv.setUnderscores( OnOff: boolean ) conv.getUnderscores; @returns( "eax" );When converting numeric data types to strings, HLA offers the option of inserting underscores at appropriate places in the numbers (i.e., where you would normally expect a comma to go). This feature in the library can be activated or deactivated with the conv.setUnderscores function. A parameter value of true activates this feature, false deactivates it.
You can test the current state of the underscore conversion by calling conv.getUnderscores which returns the boolean result in EAX (true means underscores will be output).
conv.setDelimiters( Delims: cset ) conv.getDelimiters( var Delims: cset )During the conversion from string to a numeric form, HLA will generate an exception if it encounters a character that is not a numeric digit in the specified base or the character is not an appropriate delimiter character. By default, the delimiter characters are members of the following set:
Delimiters: cset := { #0, #9, #10, #13, ' ', ',', ';', ':' };You can obtain the current delimiter set by calling the conv.getDelimiters function. You can change the current set of delimiter characters by calling the conv.setDelimiters function.
10.2 Hexadecimal Conversions
conv.byteToHex( b:byte in al );This is an internal routine intended for use by the conversions unit. It converts the byte in AL to two hex characters and outputs them starting at location [EDI]. You should use the conv.hToBuf routine rather than this routine. Unlike conv.hToBuf, this routine does not preserve the value in the EAX register.
10.2.1 Hexadecimal Numeric to String Convesions
conv.bToStr ( b:byte; size:dword; fill:char; buffer:string ); conv.wToStr ( w:word; size:dword; fill:char; buffer:string ); conv.dToStr ( d:dword; size:dword; fill:char; buffer:string ); conv.qToStr ( q:qword; size:dword; fill:char; buffer:string ); conv.tbToStr( tb:tbyte; size:dword; fill:char; buffer:string ); conv.lToStr( tb:tbyte; size:dword; fill:char; buffer:string );These routines are the general-purpose hexadecimal conversion routines. They convert their first parameter to a string of characters and store those character into the string variable passed as the last parameter. The size parameter specifies the minimum string length for the conversion. If the number requires more than this many character positions, the conversion routine will attempt to use however many characters as necessary. The string's maximum length must be large enough to hold the full result or an exception will occur. If the string conversion requires fewer than size characters, these routine right justify the value in the string and pad the remaining positions with the fill character.
10.2.2 Hexadecimal String to Numeric Conversions
conv.strTob( s:string; index:dword ) conv.strTow( s:string; index:dword ) conv.strTod( s:string; index:dword ) conv.strToq( s:string; index:dword ) conv.strTol( s:string; index:dword; var dest:lword )These routines convert characters from a string to the corresponding numeric forms. The index parameter is the index of the position in the string where conversion begins.
The eight-bit routines returns its result in AL; the 16-bit routine returns its result in AX; the 32-bit routine returns its result in EAX; the 64-bit routine returns its result in EDX:EAX; the 128-bit return returns its result in the destination operand specified as a parameter.
10.3 Integer Conversions
10.3.1 Integer Size Calculations
conv.i8Size( b:byte in al ) conv.i16Size( w:word in ax ) conv.i32Size( d:dword in eax ) conv.i64Size( q:qword ) conv.i128Size( l:lword ) conv.u8Size( b:byte in al ) conv.u16Size( w:word in al ) conv.u32Size( d:dword in eax ) conv.u64Size( q:qword ) conv.u128Size( l:lword ) conv.bSize( b:byte ); conv.wSize( w:word ); conv.dSize( d:dword ); conv.qSize( q:qword ); conv.lSize( l:lword ); conv._i8Size conv._i16Size conv._i32Size conv._u8Size conv._u16Size conv._u32Size conv._bSize conv._wSize conv._dSizeThese routines return the size, in screen print positions, it would take to print the integer (signed, unsigned, or hexadecimal) passed in the specified parameter or in the AL register (_i8Size/_u8Size/_bSize), AX register (_i16Size/_u16Size/_wSize), or EAX register (_i32Size/_u32Size/_dSize). They return their value in the EAX register. The count includes room for a minus sign if the number is negative (iXXSize routines, only). Note that these routines do not count spaces required by underscores if you've enabled underscore output in values.
10.3.2 Integer Numeric to String Conversions
conv.i8ToBuf( i8:int8 in al ) conv.i16ToBuf( i16: int16 in ax ) conv.i32ToBuf( i32: int32 in eax ) conv.i64ToBuf( q:qword ) conv.i128ToBuf( l:lword ) conv.u8ToBuf( u8: uns8 in al ) conv.u16ToBuf( u16: uns16 in ax ) conv.u32ToBuf( u32: uns32 in eax) conv.u64ToBuf( q:qword ) conv.u128ToBuf( l:lword )These routines are passed a parameter in AL (x8ToBuf), AX (x16ToBuf), EAX (x32ToBuf), or on the stack (xi64ToBuf and x128ToBuf). These routines convert the input parameter to a sequence of characters and store those characters starting at location [EDI]. They return EDI pointing at the first character beyond the converted string.
conv.i8ToStr ( b:int8; width:int32; fill:char; buffer:string ); conv.i16ToStr( w:int16; width:int32; fill:char; buffer:string ); conv.i32ToStr( d:int32; width:int32; fill:char; buffer:string ); conv.i64ToStr( q:qword; width:int32; fill:char; buffer:string ); conv.i128ToStr( l:lword; width:int32; fill:char; buffer:string ); conv.u8ToStr ( b:uns8; width:int32; fill:char; buffer:string ); conv.u16ToStr( w:uns16; width:int32; fill:char; buffer:string ); conv.u32ToStr( d:uns32; width:int32; fill:char; buffer:string ); conv.u64ToStr( q:qword; width:int32; fill:char; buffer:string ); conv.u128ToStr(l:lword; width:int32; fill:char; buffer:string );These routines translate their first parameter to a string that has a minimum of width print positions. If the number would require fewer than width print positions, the routines copy the fill character to the remaining positions in the destination string. If width is positive, the number is right justified in the string. If width is negative, the number is left justified in the string. If the string representation of the value requires more than width print positions, then these functions ignore the width and fill paramenters and use however many positions are necessary to properly display the value.
![]()
Figure 7 conv.xxxToStr Integer Conversion Format
10.3.3 Integer String to Numeric Conversions
conv.atou( bufPtr: dword in esi ); conv.atoi( bufptr: dword in esi ); conv.atoh( bufptr: dword in esi );These routines assume that ESI points at a sequence of characters representing an integer, hexadecimal, or floating point value. They convert the characters to a 64-bit numeric form and return the result in EDX:EAX. The atou and atoi routines are almost the same except that atoi allows a leading minus sign. These routines leave ESI pointing just beyond the last converted character.
An exception occurs if the number does not end with a legal delimiter character or does not begin with a legal numeric character.
conv.strTob( s:string; index:dword ) conv.strTow( s:string; index:dword ) conv.strTod( s:string; index:dword ) conv.strToq( s:string; index:dword ) conv.strTol( s:string; index:dword; var dest:lword ) conv.strToi8( s:string; index:dword ) conv.strToi16( s:string; index:dword ) conv.strToi32( s:string; index:dword ) conv.strToi64( s:string; index:dword ) conv.strToi128( s:string; index:dword; var dest:lword ) conv.strTou8( s:string; index:dword ) conv.strTou16( s:string; index:dword ) conv.strTou32( s:string; index:dword ) conv.strTou64( s:string; index:dword ) conv.strTou128( s:string; index:dword; var dest:lword )These routines convert characters from a string to the corresponding numeric forms. The index parameter is the index of the position in the string where conversion begins. These functions raise an exception if the string of characters (starting at position index) do not begin with a (heaxadeimal or decimal) numeric digit or optional sequence of delimiter characters followed by a numeric digit, or do not end with a delimiter (or the end of string).
The eight-bit routines return their result in AL; the 16-bit routines return their result in AX; the 32-bit routines return their result in EAX; the 64-bit routines return their result in EDX:EAX; and the 128-bit routines return their values in the specified destination operand.
10.4 Floating Point Conversions
These functions convert betweeen the three IEEE/Intel floating point formats and their string representation.
10.4.1 Floating Point Numeric to String Conversions, Exponential Form
The floating point numeric to string conversion routines translate the three different binary floating point formats to their string representation. There are two generic classes of these routines: those that convert their values to exponential/scientific notation and those that convert their string to a decimal form.
The conv.e80ToStr, conv.e64ToStr, and conv.e32ToStr routines convert their values to a string using scientific notation. These three routines each have four parameters: the value to convert, the field width of the result, and a destination string. These routines produce a string with the following format:
![]()
Figure 8 conv.exxToStr Conversion Format
The width parameter specifies the exact number of print positions the value will consume (i.e., the length of the resulting string). The first position holds the sign of the value. This is a space for positive values or a minus sign for negative values. If you do not want a leading space in front of positive values you can either store a "+" over the top of this space character (if the number is zero or positive) or you can call str.trim to remove any leading space.
The exponent field ('x') always uses the minimum number of digits to exactly represent the exponent. If the exponent is non-negative, then these routines preface the value with a '+'. If the exponent is negative, then these functions preface the exponent value with a '-' character.
The minimum field width you should specify is five. This allows one print position for the leading sign character, one digit for the mantissa, the "E", the exponent sign, and one exponent digit. Obviously, values greater than 1E+9 or less than 1E-9 will require additional print positions to handle the additional exponent digits.
The number of fractional digits this routines produce is "(width - 5) - # exponent digits". So you should choose your width according to the expected exponent size and the number of digits you would like to have to the right of the decimal point.
conv.e80ToStr ( r80: real80; width: uns32; buffer: string )This function converts the 80-bit extended precision r80 value to its string representation using exponential/scientific notation. This function stores the resulting string in the buffer variable whose MaxLength field must be at least width or this function will raise an exception. Note that the 80-bit extended precision format supports approximately 18 decimal digits of precision. Therefore, any digits beyond the 18th significant digit will contain garbage. Hence, your choice of width should not produce more than 18 mantissa digits.
conv.e64ToStr ( r64: real64; width: uns32; buffer: string )This function converts the 64-bit double precision r64 value to its string representation using exponential/scientific notation. This function stores the resulting string in the buffer variable whose MaxLength field must be at least width or this function will raise an exception. Note that the 64-bit double precision format supports approximately 15 decimal digits of precision. Therefore, any digits beyond the 15th significant digit will contain garbage. Hence, your choice of width should not produce more than 15 mantissa digits.
conv.e32ToStr ( r32: real32; width: uns32; buffer: string )This function converts the 32-bit single precision r32 value to its string representation using exponential/scientific notation. This function stores the resulting string in the buffer variable whose MaxLength field must be at least width or this function will raise an exception. Note that the 32-bit single precision format supports approximately 6-7 decimal digits of precision. Therefore, any digits beyond the seventh significant digit will contain garbage. Hence, your choice of width should not produce more than seven mantissa digits.
10.4.2 Floating Point Numeric to String Conversions, Decimal Form
Although scientific (exponential) notation is the most general display format for real numbers, real numbers you display in this format are very difficult to read. Therefore, the HLA conversions module also provides a set of functions that convert real values to the decimal string equivalent. Although you cannot (practically) use these decimal conversion routines for all real values, they are applicable to a wide variety of common numbers you will use in your programs.
These functions all require five parameters: the real value to convert, the width of the converted value, the number of digit positions to the right of the decimal point, a padding character, and a destination string to hold the result. These functions convert their values to the following string format:
![]()
Figure 9 conv.rxxToStr Conversion Format
The width parameter specifies the length of the resulting string. This value must be less than or equal to the destination string's MaxLength value or these functions will raise an exception. The decimalpts parameter to these functions specify the number of digits to the right of the decimal point. If this parameter contains zero, then these functions display the value as an integer (no fractional digits and no decimal point). If this parameter is non-zero, then these routines produce the specified number of decimal digits along with a decimal point.
The width parameter specifies the total size of the resulting string. If decimalpts is zero, then the width value must be at least one greater than the number of digits that appear to the left of the decimal point (the extra position is for the sign character. If the decimalpts parameter is non-zero, then width must be at least (decimalpts + 2 + # integer digits ). If width is not sufficiently large, then these functions produce a string containing width "#" characters to denote a conversion error.
If the width value is sufficiently large and the decimalpts sufficiently small then these routines will fill the extra print positions using the fill character you pass as a parameter. For example, if you convert the value -1.5 with a width of six, a decimalpts value of two, and a fill character of "*" these routines produce the string "*-1.50".
conv.r80ToStr ( r80: real80; width: uns32; decimalpts: uns32; fill: char; buffer: string )This function converts the 80-bit extended precision r80 value to its string representation using decimal notation. This function stores the resulting string in the buffer variable whose MaxLength field must be at least width or this function will raise an exception. Note that the 80-bit single precision format supports approximately 18 decimal digits of precision. Therefore, any digits beyond the 18th significant digit will contain garbage. Hence, your choice of width should not produce more than 18 mantissa digits. Do keep in mind that the average person has trouble comprehending value with more than six or seven digits. For values that are routinely outside this range you may want to use exponential form to display the number with a limited number of significant digits.
conv.r64ToStr ( r64: real64; width: uns32; decimalpts: uns32; fill: char; buffer: string )This function converts the 64-bit double precision r64 value to its string representation using decimal notation. This function stores the resulting string in the buffer variable whose MaxLength field must be at least width or this function will raise an exception. Note that the 64-bit single precision format supports approximately 15 decimal digits of precision. Therefore, any digits beyond the 15th significant digit will contain garbage. Hence, your choice of width should not produce more than 15 mantissa digits. Do keep in mind that the average person has trouble comprehending value with more than six or seven digits. For values that are routinely outside this range you may want to use exponential form to display the number with a limited number of significant digits.
conv.r32ToStr ( r32: real32; width: uns32; decimalpts: uns32; fill: char; buffer: string )This function converts the 32-bit single precision r32 value to its string representation using decimal notation. This function stores the resulting string in the buffer variable whose MaxLength field must be at least width or this function will raise an exception. Note that the 32-bit single precision format supports approximately 6-7 decimal digits of precision. Therefore, any digits beyond the seventh significant digit will contain garbage. Hence, your choice of width should not produce more than seven mantissa digits.
10.4.3 Floating Point String to Numeric Conversions
conv.atof( bufptr: dword in esi ); @returns( "st0" );This routine assumes that ESI is pointing at a sequence of characters that represents a floating point number. The characters are converted to numeric form and the result is returned in ST0. ESI is left pointing at the first character beyond the converted characters. This function raises an exception if the value begins with something other than a standard numeric delimiter character or ends with something other than a standard delimiter character (or the end of string).
This routine accepts floating point input in either decimal or exponential form.
conv.strToFlt( s:string; index:dword ); @returns( "st0" );This function converts the sequence of characters starting at position index in s to the equivalent extended precision floating point value and it leaves the result in ST0. This function raises an exception if the value begins with something other than a standard numeric delimiter character or ends with something other than a standard delimiter character (or the end of string).
This routine accepts floating point input in either decimal or exponential form.
10.5 Zero Terminated String Conversions
conv.cStrToStr( var buffer:var; dest:string )This function converts a "C-String" (zero terminated sequence of characters) to an HLA string. The buffer parameter points at the zero terminated string, conv.cStrToStr stores the resulting string into the dest operand.
Note: a function that converts HLA strings to zero-terminated strings is not necessary since HLA strings are already zero-terminated and the string variable points at the first character of the string; hence, HLA strings are already downwards compatible with C-Strings.
This function name is an alias of the str.cpyz function. That is, if you use conv.cStrToStr HLA actually links in the str.cpyz function from the strings module.
conv.a_cStrToStr( var buffer:var )This function also converts zero terminated strings to HLA strings. However, instead of storing the string data at a specified location, this routine allocates storage for the string on the heap and returns a pointer to the new string in EAX. You should use strfree to clean up the storage after you are done with the string.
This function name is an alias of the str.a_cpyz function. That is, if you use conv.a_cStrToStr HLA actually links in the str.a_cpyz function from the strings module.
10.6 Roman Numeral Conversion
conv.roman( Arabic:uns32; rmn:string )This procedure converts the specified integer value (Arabic) into a string that contains the Roman numeral representation of the value. Note that this routine only converts integer values in the range 1..3,999 to Roman numeral form. Since ASCII text doesn't allow overbars (that multiply roman digits by 1,000), this function doesn't handle really large Roman numbers. A different character set would be necessary for that.
conv.a_roman( Arabic:uns32 )Just like the routine above, but this one allocates storage for the string and returns a pointer to the string in the EAX register.
![]() |
![]() |
![]() |
![]() |
![]() |