Q63095: QB Sample Function to Convert from Floating-Point to String
Article: Q63095
Product(s): See article
Version(s): 4.00 4.00b 4.50
Operating System(s): MS-DOS
Keyword(s): ENDUSER | SR# S900608-167 B_BasicCom | mspl13_basic
Last Modified: 8-AUG-1990
This article provides a code example of a FUNCTION procedure that
always returns the string equivalent of a real number in the format
"WholeNumber.Fraction". This works around the usual behavior of the
STR$ function, which, depending on how a real number is represented in
binary, returns either a string in the form of "WholeNumber.Fraction"
or a string in scientific notation.
This information applies to Microsoft QuickBASIC versions 4.00, 4.00b,
and 4.50, to Microsoft BASIC Compiler versions 6.00 and 6.00b for
MS-DOS and MS OS/2, and to Microsoft BASIC Professional Development
System (PDS) versions 7.00 and 7.10 for MS-DOS and MS OS/2.
STR$ merely converts a SINGLE or DOUBLE into a string based on a real
number's internal representation. Because some real numbers cannot be
represented exactly in binary, the STR$ function returns some numbers
in scientific notation and others in normal notation. The RealString$
FUNCTION below never returns scientific notation, but always returns
normal notation.
Code Example
------------
The code example below provides a FUNCTION procedure that consistently
converts a real number into a string of the format "WholeNumber.Fraction".
Please note that this function is provided as a general example of how
to approach solving this programming problem. It represents only one
solution; others may be possible.
1. Description: The RealString$ function converts a DOUBLE-precision
number into a string, rounding the result to the specified
precision.
2. The parameters are as follows:
a. RealNumber - Any DOUBLE type value.
Note: You can also pass INTEGER, LONG, and SINGLE types in
conjunction with the BASIC keyword CDBL. Of course, STR$ with
the INTEGER and LONG types will yield the same result. For
example:
a$ = RealString$(CDBL(b!),10)
where b! is a variable of type SINGLE
b. MaxPrecision - Indicates the maximum number of decimal places
you are willing to tolerate to the right of the decimal point.
For this function to work properly, MaxPrecision MUST be greater
than or equal to the total number of fractional decimal places
of the value being passed in RealNumber. For example, if you are
calling this function with .005 in RealNumber, you MUST pass a
number no less than 3 in MaxPrecision. A number greater than 3
still returns "0.005" in RealString$. For example, passing 5
through MaxPrecision returns ".005" NOT "0.00500". Zeros are NOT
padded in the string to give a result the length of
MaxPrecision.
WARNING: If MaxPrecision is substantially greater than the
fractional decimal places in the value passed through parameter
RealNumber, extraneous results may be returned in RealString$.
For example:
a$ = RealString$(.05,30) returns
"0.0500000007450580596923828125"
3. Returns: RealString$ returns a string containing the string
equivalent of RealNumber. For real numbers greater than -1 and less
than 1, RealString$ always appends a zero in the 1's digit
position. For example, a$ = RealString$(.005,3) returns "0.005" in
a$.
Note: The maximum number of possible digits to the right of the
decimal point is determined by the parameter MaxPrecision. (See
above.)
'******************** RealString FUNCTION **************************
FUNCTION RealString$ (RealNumber AS DOUBLE, MaxPrecision AS INTEGER)
IF MaxPrecision < 0 OR MaxPrecision > 50 THEN
RealString$ = ""
ELSE
' Break the RealNumber into its whole and decimal parts
whole& = FIX(RealNumber#)
decimal# = ABS(RealNumber# - whole&)
' Add in a rounding factor. This compensates for numbers
' such as .05 that can't be stored exactly in binary. For
' example, .05 is represented as .04999. This is the means
' to round it up to .05 as it should be.
decimal# = decimal# + 5 * 10 ^ -(MaxPrecision% + 1)
IF decimal# >= 1 THEN
whole& = whole& + 1
END IF
' Convert the fractional part to a string
DecString$ = ""
FOR i% = 1 TO MaxPrecision + 1
DecDigit% = FIX(decimal# * 10)
DecString$ = DecString$ + RIGHT$(STR$(DecDigit%), 1)
decimal# = decimal# * 10 - FIX(decimal# * 10)
NEXT i%
' Ensure that the fractional part is equal
' in length to the maximum precision allowed
IF LEN(DecString$) > MaxPrecision THEN
DecString$ = LEFT$(DecString$, MaxPrecision%)
' Remove all trailing zeros from the end of the
' fractional part
i% = LEN(DecString$)
WHILE i% > 0
IF MID$(DecString$, i%, 1) = "0" THEN
DecString$ = LEFT$(DecString$, i% - 1)
ELSE
i% = 0
END IF
i% = i% - 1
WEND
END IF
' Include the decimal point before the fraction
IF DecString$ <> "" THEN
DecString$ = "." + DecString$
END IF
' Compose a string of the whole and fractional parts of
' the real number
RealString$ = STR$(whole&) + DecString$
END IF ' (END of IF from very top of function)
END FUNCTION
Sample Program Using This Function
----------------------------------
DECLARE FUNCTION RealString$ (RealNumber AS DOUBLE, MaxPrecision AS_
INTEGER)
CLS
PRINT RealString$(3.1415927, 7)
PRINT RealString$(437.137827#, 5)
PRINT RealString$(.000173, 10)
PRINT RealString$(99.997,2)
END
Sample Output
-------------
3.14157927
437.13783
0.000173
100
THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.
Copyright Microsoft Corporation 1986-2002.